use of edu.mit.blocks.codeblocks.Block in project openblocks by mikaelhg.
the class BlockUtilities method getBlock.
/**
* Returns a new RenderableBlock instance with the matching genusName.
* New block will also have matching label is label is not-null. May return null.
*
* @param workspace The workspace to use
* @param genusName
* @param label
*
* @requires if block associated with genusName has a non editable
* or unique block label, then "label" MUST BE NULL.
* @return A new RenderableBlock with matching genusName and label (if label is not-null).
* If no matching blocks were found, return null.
*/
public static RenderableBlock getBlock(Workspace workspace, String genusName, String label) {
if (genusName == null) {
return null;
}
// find all blocks on the page and look for any match
for (Block block : workspace.getBlocks()) {
//make sure we're not dealing with null blocks
if (block == null || block.getBlockID() == null || block.getBlockID().equals(Block.NULL)) {
continue;
}
//find the block with matching genus and either a matching label or an editable label
if (block.getGenusName().equals(genusName) && (block.isLabelEditable() || block.getBlockLabel().equals(label) || block.isInfix())) {
//but stubs of different parents do not share the same label
if (block instanceof BlockStub && !block.getBlockLabel().equals(label)) {
continue;
}
//create new renderable block instance
RenderableBlock renderable = BlockUtilities.cloneBlock(block);
//make sure renderable block is not a null instance of a block
if (renderable == null || renderable.getBlockID().equals(Block.NULL)) {
throw new RuntimeException("Invariant Violated: a valid non null blockID just" + "returned a null instance of RenderableBlock");
//please throw an exception here because it wouldn't make any sense
//if the Block is valid but it's associated RenderableBlock is not
}
//do not drop down default arguments
renderable.ignoreDefaultArguments();
//get corresponding block
Block newblock = workspace.getEnv().getBlock(renderable.getBlockID());
//make sure corresponding block is not a null instance of block
if (newblock == null || newblock.getBlockID().equals(Block.NULL)) {
throw new RuntimeException("Invariant Violated: a valid non null blockID just" + "returned a null instance of Block");
//please throw an exception here because it wouldn't make any sense
//if the Block is valid but it's associated RenderableBlock is not
}
//should not set the labels of block stubs because their labels are determined by their parent
if ((block.isLabelEditable() || block.getBlockLabel().equals(label))) {
if (label != null && !(block instanceof BlockStub)) {
if (newblock.isLabelEditable() && !newblock.labelMustBeUnique()) {
newblock.setBlockLabel(label);
}
}
}
//return renderable block
return renderable;
}
/////////////////////////////////////
//TODO: Add code here for nicknames//
/////////////////////////////////////
}
//TODO: the part below is a hack. If there are other types of blocks, we need to account for them
return null;
}
use of edu.mit.blocks.codeblocks.Block in project openblocks by mikaelhg.
the class BlockUtilities method makeNodeWithStack.
public static BlockNode makeNodeWithStack(Workspace workspace, Long blockID) {
if (isNullBlockInstance(workspace, blockID)) {
return null;
}
Block block = workspace.getEnv().getBlock(blockID);
String genus = block.getGenusName();
String parentGenus = block instanceof BlockStub ? ((BlockStub) block).getParentGenus() : null;
String label;
if (!block.labelMustBeUnique() || block instanceof BlockStub) {
label = block.getBlockLabel();
} else {
label = null;
}
BlockNode node = new BlockNode(genus, parentGenus, label);
for (BlockConnector socket : block.getSockets()) {
if (socket.hasBlock()) {
node.addChild(makeNodeWithStack(workspace, socket.getBlockID()));
}
}
if (block.hasAfterConnector()) {
node.setAfter(makeNodeWithStack(workspace, block.getAfterBlockID()));
}
return node;
}
use of edu.mit.blocks.codeblocks.Block in project openblocks by mikaelhg.
the class RenderableBlock method synchronizeLabelsAndSockets.
/**
* Updates all the labels within this block. Returns true if this update found any changed labels; false otherwise
* @return true if this update found any changed labels; false otherwise.
*/
private boolean synchronizeLabelsAndSockets() {
boolean blockLabelChanged = getBlock().getBlockLabel() != null && !blockLabel.getText().equals(getBlock().getBlockLabel());
boolean pageLabelChanged = getBlock().getPageLabel() != null && !pageLabel.getText().equals(getBlock().getPageLabel());
boolean socketLabelsChanged = false;
// are consistent.
for (int i = 0; i < getBlock().getNumSockets(); i++) {
BlockConnector socket = getBlock().getSocketAt(i);
ConnectorTag tag = this.getConnectorTag(socket);
if (tag != null) {
if (tag.getLabel() != null) {
if (!tag.getLabel().getText().equals(socket.getLabel())) {
socketLabelsChanged = synchronizeSockets();
break;
}
}
}
if (!socket.isLabelEditable()) {
socketLabelsChanged = synchronizeSockets();
break;
}
}
if (blockLabelChanged) {
blockLabel.setText(getBlock().getBlockLabel());
}
if (pageLabelChanged) {
pageLabel.setText(getBlock().getPageLabel());
}
if (blockLabelChanged || pageLabelChanged || socketLabelsChanged || commentLabelChanged) {
reformBlockShape();
commentLabelChanged = false;
}
if (BlockLinkChecker.hasPlugEquivalent(getBlock())) {
BlockConnector plug = BlockLinkChecker.getPlugEquivalent(getBlock());
Block plugBlock = workspace.getEnv().getBlock(plug.getBlockID());
if (plugBlock != null) {
if (plugBlock.getConnectorTo(blockID) == null) {
throw new RuntimeException("one-sided connection from " + getBlock().getBlockLabel() + " to " + workspace.getEnv().getBlock(blockID).getBlockLabel());
}
workspace.getEnv().getRenderableBlock(plug.getBlockID()).updateSocketSpace(plugBlock.getConnectorTo(blockID), blockID, true);
}
}
return false;
}
use of edu.mit.blocks.codeblocks.Block in project openblocks by mikaelhg.
the class FocusTraversalManager method focusPrevBlock.
/**
* Reassigns the focus to the "previous block" of the current focusBlock.
* If the current focusblock is at location n of the flatten linear vector
* of the block tree structure, then the "previous block" is located at n-1.
* In other words, the previous block is the innermost block of the previous
* socket of the parent block of the focusblock.
*
* @requires pointFocusOwner != null &&
* focusblock.getSockets() != null &&
* focusblock.getSockets() is not empty
* @modifies this.focusblock
* @effects this.focusblock now points to the "previous block"
* as described in method overview;
* @return true if the new focus is on a block that isn't null
*/
public boolean focusPrevBlock() {
//return focus to canvas if no focusblock does not exist
if (invalidBlock(focusBlock) || !workspace.getEnv().getRenderableBlock(focusBlock).isVisible()) {
setFocus(canvasFocusPoint, Block.NULL);
return false;
}
Block currentBlock = getBlock(focusBlock);
//set plug to be previous block
Block previousBlock = getPlugBlock(currentBlock);
//if plug is null, set before to be previous block
if (previousBlock == null) {
previousBlock = getBeforeBlock(currentBlock);
}
//If before is ALSO null, jump to bottom of the stack;
if (previousBlock == null) {
previousBlock = getBottomRightBlock(currentBlock);
} else {
//If at least a plug block OR (but not both) before block exist,
//then get innermost block of the previous socket of the previous block
//assumes previousBlock.getSockets is not empty, not null
Block beforeBlock = previousBlock;
//ASSUMPTION BEING MADE: assume that the list below is constructed to
//have all the sockets FOLLOWED by FOLLOWED by the after connector
//THE ORDER MUST BE KEPT TO WORK CORRECTLY! We cannot use
//BlockLinkChecker.getSocketEquivalents because the specification does
//not guarantee this precise ordering. Futhermore, an interable
//has no defined order. However, as of this writing, the current implementation
//of that method does seem to produce this ordering. But we're still not using it.
List<BlockConnector> connections = new ArrayList<BlockConnector>();
for (BlockConnector socket : previousBlock.getSockets()) {
//add sockets
connections.add(socket);
}
//add after connector
connections.add(previousBlock.getAfterConnector());
//now traverse the connections
for (BlockConnector connector : connections) {
if (connector == null || connector.getBlockID() == Block.NULL || getBlock(connector.getBlockID()) == null) {
//if null socket, move on to next socket
continue;
}
if (connector.getBlockID().equals(currentBlock.getBlockID())) {
//reached back to current block
if (!beforeBlock.getBlockID().equals(previousBlock.getBlockID())) {
//if previous block was never updated, go to bottom of stack
previousBlock = getBottomRightBlock(previousBlock);
}
setFocus(previousBlock.getBlockID());
return true;
}
//update previous block
previousBlock = getBlock(connector.getBlockID());
}
//so it seems liek all sockets are null (or sockets exist),
//so just get the bottom of the stack
previousBlock = getBottomRightBlock(previousBlock);
}
setFocus(previousBlock.getBlockID());
return true;
}
use of edu.mit.blocks.codeblocks.Block in project openblocks by mikaelhg.
the class FocusTraversalManager method getTopOfStack.
/**
* For a given block, returns the outermost (top-leftmost)
* block in the stack.
* @requires block represented by blockID != null
* @param blockID any block in a stack.
* @return the outermost block (or Top-of-Stack)
* such that the outermost block != null
*/
Long getTopOfStack(Long blockID) {
//check invariant
if (blockID == null || blockID == Block.NULL || workspace.getEnv().getBlock(blockID) == null) {
throw new RuntimeException("Invariant Violated: may not" + "iterate for outermost block over a null instance of Block");
}
//parentBlock is the topmost block in stack
Block parentBlock = null;
//go the top most block
parentBlock = getBeforeBlock(blockID);
if (parentBlock != null) {
return getTopOfStack(parentBlock.getBlockID());
}
//go to the left most block
parentBlock = getPlugBlock(blockID);
if (parentBlock != null) {
return getTopOfStack(parentBlock.getBlockID());
}
//check invariant
if (parentBlock != null) {
throw new RuntimeException("Invariant Violated: may not " + "return a null instance of block as the outermost block");
}
//If we can't traverse any deeper, then this is innermost Block.
return blockID;
}
Aggregations