Package edu.mit.blocks.renderable

Source Code of edu.mit.blocks.renderable.BlockLabel

package edu.mit.blocks.renderable;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.SwingUtilities;

import edu.mit.blocks.codeblocks.Block;
import edu.mit.blocks.codeblocks.BlockConnector;
import edu.mit.blocks.codeblocks.BlockStub;
import edu.mit.blocks.codeblockutil.LabelWidget;
import edu.mit.blocks.workspace.Workspace;
import edu.mit.blocks.workspace.WorkspaceEvent;

/**
* BlockLabel is a region on a block in which text is displayed and possibly edited.  The
* location and font of a BlockLabel is specified in BlockShape and the text displayed is specified
* by a Block, BlockLabel is the gateway for text to be rendered and modified.
*
* The key nature of a BlockLabel is that it is a JLabel when being viewed, and a JTextField
* when it is being edited.
*
* During mouse move, entered and exited events a white border is toggled around the label
* for particular blocks. This white border helps to suggest editable labels for blocks that
* have this enabled.
*/
public class BlockLabel implements MouseListener, MouseMotionListener, KeyListener {

    /**Enum for the differnt types of labels in codeblocks */
    public enum Type {
        NAME_LABEL, PAGE_LABEL, PORT_LABEL, DATA_LABEL
    }
    public final static Font blockFontSmall_Bold = new Font("Arial", Font.BOLD, 7);

    public final static Font blockFontMedium_Bold = new Font("Arial", Font.BOLD, 10);

    public final static Font blockFontLarge_Bold = new Font("Arial", Font.BOLD, 12);

    public final static Font blockFontSmall_Plain = new Font("Arial", Font.PLAIN, 7);

    public final static Font blockFontMedium_Plain = new Font("Arial", Font.PLAIN, 10);

    public final static Font blockFontLarge_Plain = new Font("Arial", Font.PLAIN, 12);

    private LabelWidget widget;

    /** These keys inputs are delegated back to renderable block */
    private final char[] validOperators = {'-', '+', '/', '*', '=', '<', '>', 'x', 'X'};

    private Long blockID;

    private BlockLabel.Type labelType;

    private double zoom = 1.0;

    protected final Workspace workspace;

    /**
     * BlockLabel Constructor
     * NOTE: A true boolean passed into the isEditable parameter does not necessarily make the label
     * editable, but a false boolean will make the label uneditable.
     */
    public BlockLabel(Workspace workspace, String initLabelText, BlockLabel.Type labelType, boolean isEditable, Color tooltipBackground) {
        //call other constructor
        this(workspace, initLabelText, labelType, isEditable, -1, false, tooltipBackground);
    }

    public BlockLabel(Workspace workspace, String initLabelText, BlockLabel.Type labelType, boolean isEditable, long blockID, boolean hasComboPopup, Color tooltipBackground) {
        this.workspace = workspace;
        if (Block.NULL.equals(blockID)) {
            throw new RuntimeException("May not pass a null block instance as the parent of a block label");
        }
        if (initLabelText == null) {
            initLabelText = "";
        }
        this.blockID = blockID;
        this.labelType = labelType;
        widget = new LabelWidget(initLabelText, workspace.getEnv().getBlock(blockID).getColor().darker(), tooltipBackground) {

            private static final long serialVersionUID = 328149080424L;

            protected void fireTextChanged(String text) {
                textChanged(text);
            }

            protected void fireGenusChanged(String genus) {
                genusChanged(genus);
            }

            protected void fireDimensionsChanged(Dimension value) {
                dimensionsChanged(value);
            }

            protected boolean isTextValid(String text) {
                return textValid(text);
            }
        };
        widget.setNumeric(workspace.getEnv().getBlock(this.blockID).getGenusName().equals("number"));

        // Only editable if the isEditable parameter was true, the label is either a Block's name or
        // socket label, the block can edit labels, and the block is not in the factory.
        widget.setEditable(
                isEditable
                && (labelType == BlockLabel.Type.NAME_LABEL || labelType == BlockLabel.Type.PORT_LABEL)
                && workspace.getEnv().getBlock(blockID).isLabelEditable()
                && !(workspace.getEnv().getRenderableBlock(blockID) instanceof FactoryRenderableBlock));
        if (labelType == null || labelType.equals(BlockLabel.Type.NAME_LABEL)) {
            widget.setFont(BlockLabel.blockFontLarge_Bold);
        } else if (labelType.equals(BlockLabel.Type.PAGE_LABEL)) {
            widget.setFont(BlockLabel.blockFontMedium_Bold);
        } else if (labelType.equals(BlockLabel.Type.PORT_LABEL)) {
            widget.setFont(BlockLabel.blockFontMedium_Bold);
        } else if (labelType.equals(BlockLabel.Type.DATA_LABEL)) {
            widget.setFont(BlockLabel.blockFontMedium_Bold);
        }
        if (workspace.getEnv().getBlock(blockID).hasSiblings()) {
            //Map<String, String> siblings = new HashMap<String, String>();
            List<String> siblingsNames = workspace.getEnv().getBlock(blockID).getSiblingsList();
            String[][] siblings = new String[siblingsNames.size() + 1][2];
            siblings[0] = new String[]{workspace.getEnv().getBlock(blockID).getGenusName(), workspace.getEnv().getBlock(blockID).getInitialLabel()};
            for (int i = 0; i < siblingsNames.size(); i++) {
                siblings[i + 1] = new String[]{siblingsNames.get(i), workspace.getEnv().getGenusWithName(siblingsNames.get(i)).getInitialLabel()};
            }
            widget.setSiblings(hasComboPopup && workspace.getEnv().getBlock(blockID).hasSiblings(), siblings);
        }

        widget.addMouseListenerToLabel(this);
        widget.addMouseMotionListenerToLabel(this);
        widget.addKeyListenerToTextField(this);

        //set initial text
        widget.updateLabelText(initLabelText);
        //add and show the textLabel initially
        widget.setEditingState(false);
    }

    public void setZoomLevel(double newZoom) {
        this.zoom = newZoom;
        widget.setZoomLevel(newZoom);
    }

    public int getAbstractWidth() {
        if (widget.hasSiblings()) {
            return (int) (widget.getWidth() / zoom) - LabelWidget.DROP_DOWN_MENU_WIDTH;
        } else {
            return (int) (widget.getWidth() / zoom);
        }
    }

    public int getAbstractHeight() {
        return (int) (widget.getHeight() / zoom);
    }

    public int getPixelWidth() {
        return widget.getWidth();
    }

    public int getPixelHeight() {
        return widget.getHeight();
    }

    public Point getPixelLocation() {
        return widget.getLocation();
    }

    public void setEditable(boolean isEditable) {
        widget.setEditable(isEditable);
    }

    public boolean editingText() {
        return widget.editingText();
    }

    public void highlightText() {
        widget.highlightText();
    }

    public void setPixelLocation(int x, int y) {
        widget.setLocation(x, y);
    }

    public String getText() {
        return widget.getText();
    }

    public void setText(String text) {
        widget.setText(text);
    }

    public void setText(boolean text) {
        widget.setText(text);
    }

    public void setText(double text) {
        widget.setText(text);
    }

    public void setToolTipText(String text) {
        widget.assignToolTipToLabel(text);
    }

    public void showMenuIcon(boolean show) {
        widget.showMenuIcon(show);
    }

    public JComponent getJComponent() {
        return widget;
    }

    public void setEditingState(boolean editing) {
        widget.setEditingState(editing);
    }

    protected int rescale(int x) {
        return (int) (x * zoom);
    }

    protected int rescale(double x) {
        return (int) (x * zoom);
    }

    protected int descale(int x) {
        return (int) (x / zoom);
    }

    protected int descale(double x) {
        return (int) (x / zoom);
    }

    /** returns the blockID for this BlockLabel */
    Long getBlockID() {
        return blockID;
    }

    protected void textChanged(String text) {
        if ((this.labelType.equals(BlockLabel.Type.NAME_LABEL) || this.labelType.equals(BlockLabel.Type.PORT_LABEL))
                && workspace.getEnv().getBlock(blockID).isLabelEditable()) {
            if (this.labelType.equals(BlockLabel.Type.NAME_LABEL)) {
                workspace.getEnv().getBlock(blockID).setBlockLabel(text);
            }
            BlockConnector plug = workspace.getEnv().getBlock(blockID).getPlug();
            // Check if we're connected to a block. If we are and the the block we're connected to
            // has stubs, update them.
            if (plug != null && plug.getBlockID() != Block.NULL) {
                if (workspace.getEnv().getBlock(plug.getBlockID()) != null) {
                    if (workspace.getEnv().getBlock(plug.getBlockID()).isProcedureDeclBlock()
                            && workspace.getEnv().getBlock(plug.getBlockID()).hasStubs()) {
                        // Blocks already store their socket names when saved so it is not necessary
                        // nor desired to call the connectors changed event again.
                        if (workspace.getEnv().getRenderableBlock(plug.getBlockID()).isLoading()) {
                            BlockStub.parentConnectorsChanged(workspace, plug.getBlockID());
                        }
                    }
                }
            }
            RenderableBlock rb = workspace.getEnv().getRenderableBlock(blockID);
            if (rb != null) {
                workspace.notifyListeners(new WorkspaceEvent(workspace, rb.getParentWidget(), blockID, WorkspaceEvent.BLOCK_RENAMED));
            }
        }
    }

    protected void genusChanged(String genus) {
        if (widget.hasSiblings()) {
            Block oldBlock = workspace.getEnv().getBlock(blockID);
            oldBlock.changeGenusTo(genus);
            RenderableBlock rb = workspace.getEnv().getRenderableBlock(blockID);
            rb.repaintBlock();
            workspace.notifyListeners(new WorkspaceEvent(workspace, rb.getParentWidget(), blockID, WorkspaceEvent.BLOCK_GENUS_CHANGED));
        }
    }

    protected void dimensionsChanged(Dimension value) {
        if (workspace.getEnv().getRenderableBlock(blockID) != null) {
          workspace.getEnv().getRenderableBlock(blockID).repaintBlock();
        }
    }

    protected boolean textValid(String text) {
        return !text.equals("")
                && BlockUtilities.isLabelValid(workspace, blockID, text);
    }

    @Override
  public void mouseClicked(MouseEvent e) {
        if (!((e.getClickCount() == 1) && widget.isEditable())) {
            workspace.getEnv().getRenderableBlock(blockID).processMouseEvent(SwingUtilities.convertMouseEvent(widget, e, widget.getParent()));
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
        if (widget.getParent() != null && widget.getParent() instanceof MouseListener) {
            workspace.getEnv().getRenderableBlock(blockID).processMouseEvent(SwingUtilities.convertMouseEvent(widget, e, widget.getParent()));
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        if (widget.getParent() != null && widget.getParent() instanceof MouseListener) {
            workspace.getEnv().getRenderableBlock(blockID).processMouseEvent(SwingUtilities.convertMouseEvent(widget, e, widget.getParent()));
        }
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        if (widget.getParent() != null && widget.getParent() instanceof MouseListener) {
            workspace.getEnv().getRenderableBlock(blockID).processMouseEvent(SwingUtilities.convertMouseEvent(widget, e,
                    widget.getParent()));
        }
    }

    @Override
    public void mouseExited(MouseEvent e) {
        if (widget.getParent() != null && widget.getParent() instanceof MouseListener) {
            workspace.getEnv().getRenderableBlock(blockID).processMouseEvent(SwingUtilities.convertMouseEvent(widget, e, widget.getParent()));
        }
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        if (widget.getParent() != null && widget.getParent() instanceof MouseMotionListener) {
            ((MouseMotionListener) widget.getParent()).mouseDragged(SwingUtilities.convertMouseEvent(widget, e, widget.getParent()));
        }
    }

    @Override
    public void mouseMoved(MouseEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_ESCAPE:
                workspace.getEnv().getRenderableBlock(blockID).requestFocus();
                return;
            case KeyEvent.VK_ENTER:
                workspace.getEnv().getRenderableBlock(blockID).requestFocus();
                return;
            case KeyEvent.VK_TAB:
                workspace.getEnv().getRenderableBlock(blockID).processKeyPressed(e);
                return;
        }
        if (workspace.getEnv().getBlock(this.blockID).getGenusName().equals("number")) {
            if (e.getKeyChar() == '-' && widget.canProcessNegativeSign()) {
                return;
            }
            for (char c : validOperators) {
                if (e.getKeyChar() == c) {
                    workspace.getEnv().getRenderableBlock(blockID).processKeyPressed(e);
                    return;
                }
            }
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }
}
TOP

Related Classes of edu.mit.blocks.renderable.BlockLabel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.