/** * @param childBlock * @param widget * @requires widget != null * @modifies * @effects Does nothing if: childBlock is invalid (null) Otherwise, remove childBlock from it's * parent block if the childBlock has a parent. If it does not have a parent, do nothing. */ private void disconnectBlock(Block childBlock, WorkspaceWidget widget) { if (childBlock == null || invalidBlockID(childBlock.getBlockID())) { return; } BlockConnector childPlug = BlockLinkChecker.getPlugEquivalent(childBlock); if (childPlug == null || !childPlug.hasBlock() || isNullBlockInstance(childPlug.getBlockID())) { return; } Block parentBlock = workspace.getEnv().getBlock(childPlug.getBlockID()); BlockConnector parentSocket = parentBlock.getConnectorTo(childBlock.getBlockID()); if (parentSocket == null) { return; } // disconector if child connector exists and has a block connected to it BlockLink link = BlockLink.getBlockLink(workspace, childBlock, parentBlock, childPlug, parentSocket); if (link == null) { return; } link.disconnect(); RenderableBlock parentRenderable = workspace.getEnv().getRenderableBlock(parentBlock.getBlockID()); if (parentRenderable == null) { throw new RuntimeException( "INCONSISTANCY VIOLATION: " + "parent block was valid, non-null, and existed.\n\tBut yet, when we get it's renderable" + "representation, we recieve a null instance.\n\tIf the Block instance of an ID is non-null" + "then its graphical RenderableBlock should be non-null as well"); } parentRenderable.blockDisconnected(parentSocket); workspace.notifyListeners( new WorkspaceEvent(workspace, widget, link, WorkspaceEvent.BLOCKS_DISCONNECTED)); }
/** * @param workspace The workspace in use * @param genusName * @param label * @requires if (label != null) then associated block.isLabelEditable() should return true * @modifies focusManager.focusblock && focusManager.focuspoint && blockCanvas * @effects Do nothing if "genusName" does not map to a valid block. Otherwise, create and add a * new block with matching genus and label properties to one of the following: 1. the current * block with focus at (0,0) relative to that block. 2. the current block with focus at next * applicable socket location 3. the canvas at the last mouse click point. Then update any * focus and block connections. */ protected void automateBlockInsertion(Workspace workspace, String genusName, String label) { TypeBlockManager typeBlockManager = workspace.getTypeBlockManager(); if (!typeBlockManager.isEnabled()) { System.err.println("AutoMateBlockInsertion invoked but typeBlockManager is disabled."); return; } // if genus is null, DO NOT insert a new block, DO NOT change the focus if (genusName == null) { return; } // get matching textual Block RenderableBlock createdRB = BlockUtilities.getBlock(workspace, genusName, null); if (createdRB == null) { return; } else { // change name of block IF AN DONLY IFF a label was passed // and the block's label was editable and the block // does not need to have a unique label if (label != null && workspace.getEnv().getBlock(createdRB.getBlockID()).isLabelEditable() && !workspace.getEnv().getBlock(createdRB.getBlockID()).labelMustBeUnique()) { workspace.getEnv().getBlock(createdRB.getBlockID()).setBlockLabel(label); } // add block typeBlockManager.addBlock(createdRB); } }
/** * @param renderable * @param widget * @param container * @requires renderable != null && renderable.blockID != null && renderable.blockID != Block.NULL * && widget != null && container != null * @modifies renderable && children blocks connected to renderable * @effects removes renderable from container and widget and re-renders renderable block, widget, * and container appropriately. Repeats for all of renderable's children. */ private void removeBlock( RenderableBlock renderable, WorkspaceWidget widget, Container container) { widget.removeBlock(renderable); container.remove(renderable); container.validate(); container.repaint(); renderable.setParentWidget(null); // Workspace.getInstance().notifyListeners(new WorkspaceEvent(widget, renderable.getBlockID(), // WorkspaceEvent.BLOCK_REMOVED)); for (BlockConnector child : BlockLinkChecker.getSocketEquivalents( workspace.getEnv().getBlock(renderable.getBlockID()))) { if (child == null || child.getBlockID().equals(Block.NULL)) { continue; } RenderableBlock childRenderable = workspace.getEnv().getRenderableBlock(child.getBlockID()); if (childRenderable == null) { continue; } removeBlock(childRenderable, widget, container); } if (renderable.hasComment()) { renderable.removeComment(); } workspace.notifyListeners( new WorkspaceEvent( workspace, widget, renderable.getBlockID(), WorkspaceEvent.BLOCK_REMOVED)); }
/** * @param block * @requires block must be a valid block. That is, block may not be such that block == null || * block.getBlockID() == null || block.getBlockID() == Block.NULL || block.getBlockID() == -1 * || Block.getBlock(block.getBlockID()) == null || * Block.getBlock(block.getBlockID()).getGenusName() == null || * Block.getBlock(block.getBlockID()).getGenusName().length() == 0 || * Block.getBlock(block.getBlockID()).getBlockLabel() == null * @modifies Objects modified by this method is undefined * @effects The effects of this method is unknown */ private void addBlock(RenderableBlock block) { // check invariant if (block == null || block.getBlockID() == null || block.getBlockID().equals(Block.NULL) || workspace.getEnv().getBlock(block.getBlockID()) == null || workspace.getEnv().getBlock(block.getBlockID()).getGenusName() == null || workspace.getEnv().getBlock(block.getBlockID()).getGenusName().length() == 0 || workspace.getEnv().getBlock(block.getBlockID()).getBlockLabel() == null) { throw new RuntimeException( "Invariant Violated: may not pass an invalid instance of renderabel block"); } // ignore default arguments block.ignoreDefaultArguments(); this.blockCanvas.getCanvas().add(block, 0); block.setLocation(0, 0); Long parentBlockID = this.focusManager.getFocusBlockID(); if (invalidBlockID(parentBlockID)) { new BlockDropAnimator( workspace, this.focusManager.getCanvasPoint(), block, workspace.getEnv().getRenderableBlock(parentBlockID)); } else { RenderableBlock parentBlock = workspace.getEnv().getRenderableBlock(parentBlockID); new BlockDropAnimator( workspace, SwingUtilities.convertPoint( parentBlock, this.focusManager.getBlockPoint(), this.blockCanvas.getCanvas()), block, workspace.getEnv().getRenderableBlock(parentBlockID)); } this.focusManager.setFocus(block.getBlockID()); }
/** * Helper method that recursively finds and removes all the blocks connected to the bottom of this * block, including this block. * * @param afterBlock - RenderableBlock we start removing at * @param widget - WorkspaceWidget that the block is using * @param container - Container the block is stored in */ private void removeAfterBlock( RenderableBlock afterBlock, WorkspaceWidget widget, Container container) { if (workspace.getEnv().getBlock(afterBlock.getBlockID()).getAfterBlockID() != Block.NULL) { removeAfterBlock( workspace .getEnv() .getRenderableBlock( workspace.getEnv().getBlock(afterBlock.getBlockID()).getAfterBlockID()), widget, container); } removeChildrenBlock(afterBlock, widget, container); }
protected void automateAddition(Workspace workspace, char character) { TypeBlockManager typeBlockManager = workspace.getTypeBlockManager(); if (!typeBlockManager.isEnabled()) { System.err.println("AutoMateMultiplication invoked but typeBlockManager is disabled."); return; } // get focus block Long parentBlockID = typeBlockManager.focusManager.getFocusBlockID(); if (isNullBlockInstance(parentBlockID)) { // focus on canvas automateBlockInsertion(workspace, "sum", null); } else { Block parentBlock = workspace.getEnv().getBlock(parentBlockID); if (parentBlock.getGenusName().equals("string")) { // focus on string block automateBlockInsertion(workspace, "string-append", null); } else if (parentBlock.getGenusName().equals("string-append")) { // focus on string append block automateBlockInsertion(workspace, "string-append", null); } else { // focus on any other block automateBlockInsertion(workspace, "sum", null); } } }
/** assumes number and differen genus exist and number genus has ediitabel lable */ protected void automateNegationInsertion(Workspace workspace) { TypeBlockManager typeBlockManager = workspace.getTypeBlockManager(); if (!typeBlockManager.isEnabled()) { System.err.println("AutoMateNegationInsertion invoked but typeBlockManager is disabled."); return; } // ====================>>>>>>>>>>>>>>>>>>>>>>>>> // ====================focus coming in>>>>>>>>>> TODO // ====================>>>>>>>>>>>>>>>>>>>>>>>>> // get focus block Long parentBlockID = typeBlockManager.focusManager.getFocusBlockID(); if (isNullBlockInstance(parentBlockID)) { // focus on canvas automateBlockInsertion(workspace, "number", "-"); } else { Block parentBlock = workspace.getEnv().getBlock(parentBlockID); if (parentBlock.isDataBlock()) { // focus on a data block automateBlockInsertion(workspace, "difference", null); } else { // focus on a non-data block automateBlockInsertion(workspace, "number", "-"); } } }
/** Implement MouseListener interface highlight button state */ public void mouseEntered(MouseEvent e) { super.mouseEntered(e); this.setBorder(BorderFactory.createLineBorder(Color.yellow)); Comment comment = workspace.getEnv().getRenderableBlock(getBlockID()).getComment(); comment.setVisible(true); comment.showOnTop(); }
public String translate(Long blockId) throws SocketNullException, SubroutineNotDeclaredException { TranslatorBlockFactory translatorBlockFactory = new TranslatorBlockFactory(); Block block = workspace.getEnv().getBlock(blockId); TranslatorBlock rootTranslatorBlock = translatorBlockFactory.buildTranslatorBlock( this, blockId, block.getGenusName(), "", "", block.getBlockLabel()); return rootTranslatorBlock.toCode(); }
/** Implement MouseListener interface de-highlight button state */ public void mouseExited(MouseEvent e) { super.mouseExited(e); this.setBorder(BorderFactory.createLineBorder(Color.gray)); Comment comment = workspace.getEnv().getRenderableBlock(getBlockID()).getComment(); if (!isActive()) { comment.setVisible(false); } }
private void traverseFocus(Direction dir) { if (isNullBlockInstance(focusManager.getFocusBlockID())) { if (dir == Direction.UP) { blockCanvas.getVerticalModel().setValue(blockCanvas.getVerticalModel().getValue() - 5); } else if (dir == Direction.DOWN) { blockCanvas.getVerticalModel().setValue(blockCanvas.getVerticalModel().getValue() + 5); } else if (dir == Direction.LEFT) { blockCanvas.getHorizontalModel().setValue(blockCanvas.getHorizontalModel().getValue() - 5); } else if (dir == Direction.RIGHT) { blockCanvas.getHorizontalModel().setValue(blockCanvas.getHorizontalModel().getValue() + 5); } else if (dir == Direction.ESCAPE) { // according to the focus manager, the canvas already // has focus. So, just request focus again. this.blockCanvas.getCanvas().requestFocus(); } else if (dir == Direction.ENTER) { } } else { if (dir == Direction.UP) { focusManager.focusBeforeBlock(); } else if (dir == Direction.DOWN) { focusManager.focusAfterBlock(); } else if (dir == Direction.LEFT) { focusManager.focusPrevBlock(); } else if (dir == Direction.RIGHT) { focusManager.focusNextBlock(); } else if (dir == Direction.ESCAPE) { RenderableBlock block = workspace.getEnv().getRenderableBlock(focusManager.getFocusBlockID()); Point location = SwingUtilities.convertPoint(block, new Point(0, 0), this.blockCanvas.getCanvas()); this.focusManager.setFocus(location, Block.NULL); this.blockCanvas.getCanvas().requestFocus(); } else if (dir == Direction.ENTER) { workspace .getEnv() .getRenderableBlock(focusManager.getFocusBlockID()) .switchToLabelEditingMode(true); } } }
private void pasteStack(BlockNode node) { // ====================>>>>>>>>>>>>>>>>>>>>>>>>> // ====================focus coming in>>>>>>>>>> TODO // ====================>>>>>>>>>>>>>>>>>>>>>>>>> if (node == null) { return; } WorkspaceWidget widget = null; Iterable<WorkspaceWidget> widgets = null; Point spot = null; if (invalidBlockID(focusManager.getFocusBlockID())) { // canvas has focus Point location = SwingUtilities.convertPoint( this.blockCanvas.getCanvas(), this.focusManager.getCanvasPoint(), workspace); widget = workspace.getWidgetAt(location); spot = SwingUtilities.convertPoint( this.blockCanvas.getCanvas(), this.focusManager.getCanvasPoint(), widget.getJComponent()); } else { RenderableBlock focusRenderable = workspace.getEnv().getRenderableBlock(focusManager.getFocusBlockID()); widget = focusRenderable.getParentWidget(); spot = focusRenderable.getLocation(); } if (widget == null) { // TODO: To be examined and fixed, occurs on macs JOptionPane.showMessageDialog( frame, "Please click somewhere on the canvas first.", "Error", JOptionPane.PLAIN_MESSAGE); // throw new RuntimeException("Why are we adding a block to a null widget?"); } else { // checks to see if the copied block still exists if (BlockUtilities.blockExists(workspace, node)) { // create mirror block and mirror childrens spot.translate(10, 10); RenderableBlock mirror = BlockUtilities.makeRenderable(workspace, node, widget); mirror.setLocation(spot); mirror.moveConnectedBlocks(); // make sure the childrens are placed correctly } else { // TODO: future version, allow them to paste JOptionPane.showMessageDialog( frame, "You cannot paste blocks that are currently NOT on the canvas." + "\nThis function will be available in a future version.\n", "Error", JOptionPane.PLAIN_MESSAGE); } } }
/** Implement MouseListener interface toggle collapse state of block if button pressed */ public void mouseClicked(MouseEvent e) { toggle(); RenderableBlock rb = workspace.getEnv().getRenderableBlock(getBlockID()); rb.getComment().setVisible(isActive()); workspace.notifyListeners( new WorkspaceEvent( workspace, rb.getComment().getCommentSource().getParentWidget(), WorkspaceEvent.BLOCK_COMMENT_VISBILITY_CHANGE)); update(); rb.revalidate(); rb.repaint(); workspace.getMiniMap().repaint(); }
protected void automateMultiplication(Workspace workspace, char character) { TypeBlockManager typeBlockManager = workspace.getTypeBlockManager(); if (!typeBlockManager.isEnabled()) { System.err.println("AutoMateMultiplication invoked but typeBlockManager is disabled."); return; } if (!isNullBlockInstance(typeBlockManager.focusManager.getFocusBlockID())) { Block parentBlock = workspace.getEnv().getBlock(typeBlockManager.focusManager.getFocusBlockID()); if (parentBlock.getGenusName().equals("number")) { automateBlockInsertion(workspace, "product", null); return; } } automateAutoComplete(workspace, character); return; }
private void removeChildrenBlock( RenderableBlock renderable, WorkspaceWidget widget, Container container) { widget.removeBlock(renderable); container.remove(renderable); container.validate(); container.repaint(); renderable.setParentWidget(null); // Workspace.getInstance().notifyListeners(new WorkspaceEvent(widget, renderable.getBlockID(), // WorkspaceEvent.BLOCK_REMOVED)); for (BlockConnector child : workspace.getEnv().getBlock(renderable.getBlockID()).getSockets()) { if (child == null || child.getBlockID().equals(Block.NULL)) { continue; } RenderableBlock childRenderable = workspace.getEnv().getRenderableBlock(child.getBlockID()); if (childRenderable == null) { continue; } removeBlock(childRenderable, widget, container); } // If it is a procedure block, we want to delete the entire stack if (workspace.getEnv().getBlock(renderable.getBlockID()).isProcedureDeclBlock()) { if (workspace.getEnv().getBlock(renderable.getBlockID()).getAfterBlockID() != Block.NULL) { removeAfterBlock( workspace .getEnv() .getRenderableBlock( workspace.getEnv().getBlock(renderable.getBlockID()).getAfterBlockID()), widget, container); this.disconnectBlock( workspace .getEnv() .getBlock(workspace.getEnv().getBlock(renderable.getBlockID()).getAfterBlockID()), widget); } } if (renderable.hasComment()) { renderable.removeComment(); } workspace.notifyListeners( new WorkspaceEvent( workspace, widget, renderable.getBlockID(), WorkspaceEvent.BLOCK_REMOVED)); }
/** setup current visual state of button */ public void update() { RenderableBlock rb = workspace.getEnv().getRenderableBlock(getBlockID()); if (rb != null) { int x = 5; int y = 7; if (rb.getBlock().isCommandBlock()) { y -= 2; x -= 3; } if (rb.getBlock().isDataBlock() || rb.getBlock().isFunctionBlock()) { x += 6; y -= 2; } if (rb.getBlock().isInfix() && rb.getBlock().getSocketAt(0) != null) { if (!rb.getBlock().getSocketAt(0).hasBlock()) { x += 30; } else { if (rb.getSocketSpaceDimension(rb.getBlock().getSocketAt(0)) != null) { x += rb.getSocketSpaceDimension(rb.getBlock().getSocketAt(0)).width + 2; } } y += 2; x += 1; } x = rb.rescale(x); y = rb.rescale(y); setLocation(x, y); setSize(rb.rescale(14), rb.rescale(14)); if (isActive()) { setText("?"); this.setForeground(new Color(255, 255, 0)); } else { setText("?"); this.setForeground(Color.lightGray); } rb.setComponentZOrder(this, 0); } }
/** * @requires this.blockCanvas.getCanvas() != null * @param character */ private void displayAutoCompletePanel(char character) { // ====================>>>>>>>>>>>>>>>>>>>>>>>>> // ====================focus coming in>>>>>>>>>> TODO // ====================>>>>>>>>>>>>>>>>>>>>>>>>> if (invalidBlockID(focusManager.getFocusBlockID())) { // canvas has focus this.blockCanvas.getCanvas().add(autoCompletePanel, JLayeredPane.DRAG_LAYER); autoCompletePanel.setLocation(this.focusManager.getCanvasPoint()); autoCompletePanel.setVisible(true); autoCompletePanel.requestFocus(); } else { // renderableblock has focus this.blockCanvas.getCanvas().add(autoCompletePanel, JLayeredPane.DRAG_LAYER); RenderableBlock block = workspace.getEnv().getRenderableBlock(focusManager.getFocusBlockID()); Point location = SwingUtilities.convertPoint( block, this.focusManager.getBlockPoint(), this.blockCanvas.getCanvas()); location.translate(10, 10); autoCompletePanel.setLocation(location); autoCompletePanel.setVisible(true); autoCompletePanel.requestFocus(); } autoCompletePanel.setText(String.valueOf(character)); }
private boolean isNullBlockInstance(Long blockID) { if (blockID == null) { return true; } else if (blockID.equals(Block.NULL)) { return true; } else if (workspace.getEnv().getBlock(blockID) == null) { return true; } else if (workspace.getEnv().getBlock(blockID).getBlockID() == null) { return true; } else if (workspace.getEnv().getBlock(blockID).getBlockID().equals(Block.NULL)) { return true; } else if (workspace.getEnv().getRenderableBlock(blockID) == null) { return true; } else if (workspace.getEnv().getRenderableBlock(blockID).getBlockID() == null) { return true; } else if (workspace.getEnv().getRenderableBlock(blockID).getBlockID().equals(Block.NULL)) { return true; } else { return false; } }
/** * @requires the current block with focus must exist with non-null ID in a non-null widget with a * non-null parent * @modifies the current block with focus * @effects removes the current block with focus and children from the GUI and destroys the link * between the block with focus and it's parent block if one exist and children blocks if it * has childrens. */ private void deleteBlockAndChildren() { // ====================>>>>>>>>>>>>>>>>>>>>>>>>> // ====================focus coming in>>>>>>>>>>TODO // ====================>>>>>>>>>>>>>>>>>>>>>>>>> // Do not delete null block references. Otherwise, get Block and RenderableBlock instances. if (isNullBlockInstance(focusManager.getFocusBlockID())) { throw new RuntimeException("TypeBlockManager: deleting a null block references."); } Block block = workspace.getEnv().getBlock(focusManager.getFocusBlockID()); RenderableBlock renderable = workspace.getEnv().getRenderableBlock(block.getBlockID()); // get workspace widget associated with current focus WorkspaceWidget widget = renderable.getParentWidget(); // do not delete block instances in null widgets if (widget == null) { throw new RuntimeException("TypeBlockManager: do not delete blocks with no parent widget."); // return; } // get parent container of this graphical representation Container container = renderable.getParent(); // do not delete block instances in null parents if (container == null) { throw new RuntimeException( "TypeBlockManager: do not delete blocks with no parent container."); // return; } // get the Block's location on the canvas Point location = SwingUtilities.convertPoint(renderable, new Point(0, 0), this.blockCanvas.getCanvas()); // for every valid and active connection, disconnect it. Long parentID = null; if (validConnection(block.getPlug())) { parentID = block.getPlugBlockID(); this.disconnectBlock(block, widget); if (validConnection(block.getAfterConnector())) { disconnectBlock(workspace.getEnv().getBlock(block.getAfterBlockID()), widget); } } else if (validConnection(block.getBeforeConnector())) { parentID = block.getBeforeBlockID(); BlockConnector parentConnectorToBlock = workspace.getEnv().getBlock(parentID).getConnectorTo(block.getBlockID()); this.disconnectBlock(block, widget); if (validConnection(block.getAfterConnector())) { Long afterBlockID = block.getAfterBlockID(); disconnectBlock(workspace.getEnv().getBlock(afterBlockID), widget); if (parentID != null) { BlockLink link = BlockLinkChecker.canLink( workspace, workspace.getEnv().getBlock(parentID), workspace.getEnv().getBlock(afterBlockID), parentConnectorToBlock, workspace.getEnv().getBlock(afterBlockID).getBeforeConnector()); if (link != null) { link.connect(); workspace.notifyListeners( new WorkspaceEvent( workspace, workspace.getEnv().getRenderableBlock(link.getPlugBlockID()).getParentWidget(), link, WorkspaceEvent.BLOCKS_CONNECTED)); workspace.getEnv().getRenderableBlock(link.getPlugBlockID()).repaintBlock(); workspace.getEnv().getRenderableBlock(link.getPlugBlockID()).repaint(); workspace.getEnv().getRenderableBlock(link.getPlugBlockID()).moveConnectedBlocks(); workspace.getEnv().getRenderableBlock(link.getSocketBlockID()).repaintBlock(); workspace.getEnv().getRenderableBlock(link.getSocketBlockID()).repaint(); } } } } else if (validConnection(block.getAfterConnector())) { parentID = block.getAfterBlockID(); } // remove form widget and container this.removeChildrenBlock(renderable, widget, container); // <<<<<<<<<<<<<<<<<<<<<<<<<<========================== // <<<<<<<<<<<<<<<<<<<<<<<<<<focus changing, coming out TODO // <<<<<<<<<<<<<<<<<<<<<<<<<<========================== // If the deleted block had a parent, give the parent the focus, // Otherwise, give the focus to the canvas (NOT BLOCK CANVAS) if (invalidBlockID(parentID)) { this.focusManager.setFocus(location, Block.NULL); this.blockCanvas.getCanvas().requestFocus(); return; } else { this.focusManager.setFocus(parentID); this.blockCanvas.getCanvas().requestFocus(); return; } }
public Block getBlock(Long blockId) { return workspace.getEnv().getBlock(blockId); }