griffpatch / Scratch3-Dev-Tools

Scratch 3 Dev Tools Browser Extension
GNU General Public License v3.0
35 stars 18 forks source link

[Feature Request] Go to definition option when corner clicking a custom block #26

Closed Explosion-Scratch closed 4 years ago

Explosion-Scratch commented 4 years ago

Hi there! So, when corner clicking a custom block in scratch 2.0 there was a 'go to definition' option which would center the view on the definition of the custom block, it looks like this in scratch 3.0 with a userscript of mine: screenshot (Also the colored context menus) Here is the code from the userscript, maybe you could implement this in this addon?

// ==UserScript==
// @name Better Context Menus for Scratch 3
// @version 0.2
// @namespace https://github.com/forkphorus/cat-plus
// @match https://scratch.mit.edu/projects/*
// @run-at document-idle
// ==/UserScript==

'use strict';

window.addEventListener('load', function() {

  let workspace = Blockly.getMainWorkspace();
  let hooked = false;

  // Maps block opcodes to our custom context menu handler, if any.
  // Handlers are passed the menu options list and the Blockly SVG block
  // Handlers are expected to modify the options list in place in any way they choose (push, sort, pop, etc.)
  const menuLibrary = {
    // Add a way to rename variables from their reference
    data_variable: variableRenameFactory(3, 'variable'),

    // Add a way to rename lists from their reference
    data_listcontents: variableRenameFactory(3, 'list'),

    // This doesn't work. Seems to be an editor and scratch-vm desync.
    // event_broadcast: variableRenameFactory(3, 'broadcast'),

    // TODO: consider rename options on var sets, var changes, list gets, etc.

    // Add a way to jump to a block's definition on procedure call blocks
    procedures_call(options, block) {
      options.push({
        enabled: true,
        text: "Go To Definition",
        callback() {
          const procCode = block.procCode_;
          for (const block of workspace.getAllBlocks()) {
            if (block.type === 'procedures_prototype' && block.procCode_ === procCode) {
              const parent = block.parentBlock_;
              scrollToBlock(parent);
              break;
            }
          }
        },
      });
    },
  };

  function variableRenameFactory(insertIndex, type) {
    return function(options, block) {
      options.splice(insertIndex, 0, {
        enabled: true,
        text: `Rename ${type}`,
        callback() {
          const target = block.childBlocks_.length > 0 ? block.childBlocks_[0] : block;

          const inputList = target.inputList;
          const fieldRow = inputList[0].fieldRow;
          const variable = fieldRow[0].variable_;
          const variableId = variable.id_;
          const oldName = variable.name;

          // prompt() isn't perfect but works well enough for this use case
          const newName = prompt(`Rename '${oldName}' ${type} to:`, oldName);
          if (typeof newName !== 'string') {
            return;
          }
          workspace.renameVariableById(variableId, newName);
        },
      });
    };
  }

  function scrollToBlock(block) {
    const MARGIN = 20;
    const position = block.getRelativeToSurfaceXY();
    const metrics = workspace.getMetrics();
    const x = position.x * workspace.scale - metrics.contentLeft;
    const y = position.y * workspace.scale - metrics.contentTop;
    workspace.scrollbar.set(x - MARGIN, y - MARGIN);
  }

  function hook() {
    hooked = true;

    // We add our own change listener to react to all block creations
    workspace.addChangeListener(function(change) {
      if (change.type !== 'create') {
        return;
      }

      // change.ids is a list of blocks that have been created.
      for (const id of change.ids) {
        const block = workspace.getBlockById(id);
        if (!block) continue;
        const type = block.type;

        if (type in menuLibrary) {
          // customContextMenu will be called when a block's context menu is accessed.
          // It is passed a list it is expected to modify it in place.
          // Retain the original customContextMenu() (if any) to avoid breaking behavior.
          const nativeCustomContextMenu = block.customContextMenu;
          block.customContextMenu = function(options) {
            if (nativeCustomContextMenu) {
              nativeCustomContextMenu.call(this, options);
            }
            menuLibrary[type](options, this);
          }
        }
      }
    });
  }

  // If the workspace is already available, then we hook right away.
  if (workspace) {
    hook();
  } else {
    // Probably a project page outside of the editor.
    // Wait until the user sees inside before hooking since the editor object won't exist yet.
    document.body.addEventListener('click', function(e) {
      if (!hooked && e.target.closest('.see-inside-button')) {
        // The editor will be defined after Scratch's handler runs.
        setImmediate(function() {
          workspace = Blockly.getMainWorkspace();
          hook();
        });
      }
    });
  }

});
Joeclinton1 commented 4 years ago

Why not just submit a pull request?

Also, you can already go to a custom blocks definition by clicking the middle button.

Explosion-Scratch commented 4 years ago

@Joeclinton I have no idea how to code js, I only know python. Also by 'the middle button' do you mean scroll wheel click? What about people who don't have a physical mouse?

griffpatch commented 4 years ago

Hey there, yes - I already have a go to definition implemented, but it is currently accessible through the middle click... I will have to see if I can add it to the existing context menu too perhaps for compatibility.

On Wed, 2 Sep 2020 at 02:50, --Explosion-- notifications@github.com wrote:

@JOECLINTON https://github.com/JOECLINTON I have no idea how to code js, I only know python. Also by 'the middle button' do you mean scroll wheel click? What about people who don't have a physical mouse?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/griffpatch/Scratch3-Dev-Tools/issues/26#issuecomment-685233521, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTM3PSPAUVYDYCDMOZENJTSDWQFVANCNFSM4QSIGMQQ .

Explosion-Scratch commented 4 years ago

Cool! Thanks! :)

Akash-Karthik commented 4 years ago

why not close the issue

scratchusernamemrtbts commented 4 years ago

Hey there, yes - I already have a go to definition implemented, but it is currently accessible through the middle click... I will have to see if I can add it to the existing context menu too perhaps for compatibility.

I think you should add it because some people that doesn't have middle click like me can’t access that thing