예제 #1
0
 private SVGIcon getIcon(int type) {
   SVGIcon ret = icons[type];
   if (ret != null) {
     return ret;
   } else {
     String iconName = iconNames[type];
     if (iconName == null) {
       return null;
     } else {
       ret = Icons.getIcon(iconName);
       if (ret == null) {
         iconNames[type] = null;
       } else {
         icons[type] = ret;
       }
       return ret;
     }
   }
 }
예제 #2
0
class NotGate extends InstanceFactory {
  public static final AttributeOption SIZE_NARROW =
      new AttributeOption(Integer.valueOf(20), Strings.getter("gateSizeNarrowOpt"));
  public static final AttributeOption SIZE_WIDE =
      new AttributeOption(Integer.valueOf(30), Strings.getter("gateSizeWideOpt"));
  public static final Attribute<AttributeOption> ATTR_SIZE =
      Attributes.forOption(
          "size", Strings.getter("gateSizeAttr"), new AttributeOption[] {SIZE_NARROW, SIZE_WIDE});

  private static final String RECT_LABEL = "1";
  private static final Icon toolIcon = Icons.getIcon("notGate.gif");
  private static final Icon toolIconRect = Icons.getIcon("notGateRect.gif");
  private static final Icon toolIconDin = Icons.getIcon("dinNotGate.gif");

  public static InstanceFactory FACTORY = new NotGate();

  private NotGate() {
    super("NOT Gate", Strings.getter("notGateComponent"));
    setAttributes(
        new Attribute[] {
          StdAttr.FACING,
          StdAttr.WIDTH,
          ATTR_SIZE,
          GateAttributes.ATTR_OUTPUT,
          StdAttr.LABEL,
          StdAttr.LABEL_FONT,
        },
        new Object[] {
          Direction.EAST,
          BitWidth.ONE,
          SIZE_WIDE,
          GateAttributes.OUTPUT_01,
          "",
          StdAttr.DEFAULT_LABEL_FONT,
        });
    setFacingAttribute(StdAttr.FACING);
    setKeyConfigurator(new BitWidthConfigurator(StdAttr.WIDTH));
  }

  @Override
  public Bounds getOffsetBounds(AttributeSet attrs) {
    Object value = attrs.getValue(ATTR_SIZE);
    if (value == SIZE_NARROW) {
      Direction facing = attrs.getValue(StdAttr.FACING);
      if (facing == Direction.SOUTH) return Bounds.create(-9, -20, 18, 20);
      if (facing == Direction.NORTH) return Bounds.create(-9, 0, 18, 20);
      if (facing == Direction.WEST) return Bounds.create(0, -9, 20, 18);
      return Bounds.create(-20, -9, 20, 18);
    } else {
      Direction facing = attrs.getValue(StdAttr.FACING);
      if (facing == Direction.SOUTH) return Bounds.create(-9, -30, 18, 30);
      if (facing == Direction.NORTH) return Bounds.create(-9, 0, 18, 30);
      if (facing == Direction.WEST) return Bounds.create(0, -9, 30, 18);
      return Bounds.create(-30, -9, 30, 18);
    }
  }

  @Override
  public void propagate(InstanceState state) {
    Value in = state.getPort(1);
    Value out = in.not();
    out = Buffer.repair(state, out);
    state.setPort(0, out, GateAttributes.DELAY);
  }

  //
  // methods for instances
  //
  @Override
  protected void configureNewInstance(Instance instance) {
    configurePorts(instance);
    instance.addAttributeListener();
    String gateShape = AppPreferences.GATE_SHAPE.get();
    configureLabel(instance, gateShape.equals(AppPreferences.SHAPE_RECTANGULAR), null);
  }

  @Override
  protected void instanceAttributeChanged(Instance instance, Attribute<?> attr) {
    if (attr == ATTR_SIZE || attr == StdAttr.FACING) {
      instance.recomputeBounds();
      configurePorts(instance);
      String gateShape = AppPreferences.GATE_SHAPE.get();
      configureLabel(instance, gateShape.equals(AppPreferences.SHAPE_RECTANGULAR), null);
    }
  }

  private void configurePorts(Instance instance) {
    Object size = instance.getAttributeValue(ATTR_SIZE);
    Direction facing = instance.getAttributeValue(StdAttr.FACING);
    int dx = size == SIZE_NARROW ? -20 : -30;

    Port[] ports = new Port[2];
    ports[0] = new Port(0, 0, Port.OUTPUT, StdAttr.WIDTH);
    Location out = Location.create(0, 0).translate(facing, dx);
    ports[1] = new Port(out.getX(), out.getY(), Port.INPUT, StdAttr.WIDTH);
    instance.setPorts(ports);
  }

  @Override
  protected Object getInstanceFeature(final Instance instance, Object key) {
    if (key == ExpressionComputer.class) {
      return new ExpressionComputer() {
        public void computeExpression(Map<Location, Expression> expressionMap) {
          Expression e = expressionMap.get(instance.getPortLocation(1));
          if (e != null) {
            expressionMap.put(instance.getPortLocation(0), Expressions.not(e));
          }
        }
      };
    }
    return super.getInstanceFeature(instance, key);
  }

  //
  // painting methods
  //
  @Override
  public void paintIcon(InstancePainter painter) {
    Graphics g = painter.getGraphics();
    g.setColor(Color.black);
    if (painter.getGateShape() == AppPreferences.SHAPE_RECTANGULAR) {
      if (toolIconRect != null) {
        toolIconRect.paintIcon(painter.getDestination(), g, 2, 2);
      } else {
        g.drawRect(0, 2, 16, 16);
        GraphicsUtil.drawCenteredText(g, RECT_LABEL, 8, 8);
        g.drawOval(16, 8, 4, 4);
      }
    } else if (painter.getGateShape() == AppPreferences.SHAPE_DIN40700) {
      if (toolIconDin != null) {
        toolIconDin.paintIcon(painter.getDestination(), g, 2, 2);
      } else {
        g.drawRect(0, 2, 16, 16);
        GraphicsUtil.drawCenteredText(g, RECT_LABEL, 8, 8);
        g.drawOval(16, 8, 4, 4);
      }
    } else {
      if (toolIcon != null) {
        toolIcon.paintIcon(painter.getDestination(), g, 2, 2);
      } else {
        int[] xp = new int[4];
        int[] yp = new int[4];
        xp[0] = 15;
        yp[0] = 10;
        xp[1] = 1;
        yp[1] = 3;
        xp[2] = 1;
        yp[2] = 17;
        xp[3] = 15;
        yp[3] = 10;
        g.drawPolyline(xp, yp, 4);
        g.drawOval(15, 8, 4, 4);
      }
    }
  }

  @Override
  public void paintGhost(InstancePainter painter) {
    paintBase(painter);
  }

  @Override
  public void paintInstance(InstancePainter painter) {
    painter.getGraphics().setColor(Color.BLACK);
    paintBase(painter);
    painter.drawPorts();
    painter.drawLabel();
  }

  private void paintBase(InstancePainter painter) {
    Graphics g = painter.getGraphics();
    Direction facing = painter.getAttributeValue(StdAttr.FACING);
    Location loc = painter.getLocation();
    int x = loc.getX();
    int y = loc.getY();
    g.translate(x, y);
    double rotate = 0.0;
    if (facing != null && facing != Direction.EAST && g instanceof Graphics2D) {
      rotate = -facing.toRadians();
      ((Graphics2D) g).rotate(rotate);
    }

    Object shape = painter.getGateShape();
    if (shape == AppPreferences.SHAPE_RECTANGULAR) {
      paintRectangularBase(g, painter);
    } else if (shape == AppPreferences.SHAPE_DIN40700) {
      int width = painter.getAttributeValue(ATTR_SIZE) == SIZE_NARROW ? 20 : 30;
      PainterDin.paintAnd(painter, width, 18, true);
    } else {
      PainterShaped.paintNot(painter);
    }

    if (rotate != 0.0) {
      ((Graphics2D) g).rotate(-rotate);
    }
    g.translate(-x, -y);
  }

  private void paintRectangularBase(Graphics g, InstancePainter painter) {
    GraphicsUtil.switchToWidth(g, 2);
    if (painter.getAttributeValue(ATTR_SIZE) == SIZE_NARROW) {
      g.drawRect(-20, -9, 14, 18);
      GraphicsUtil.drawCenteredText(g, RECT_LABEL, -13, 0);
      g.drawOval(-6, -3, 6, 6);
    } else {
      g.drawRect(-30, -9, 20, 18);
      GraphicsUtil.drawCenteredText(g, RECT_LABEL, -20, 0);
      g.drawOval(-10, -5, 9, 9);
    }
    GraphicsUtil.switchToWidth(g, 1);
  }

  static void configureLabel(Instance instance, boolean isRectangular, Location control) {
    Object facing = instance.getAttributeValue(StdAttr.FACING);
    Bounds bds = instance.getBounds();
    int x;
    int y;
    int halign;
    if (facing == Direction.NORTH || facing == Direction.SOUTH) {
      x = bds.getX() + bds.getWidth() / 2 + 2;
      y = bds.getY() - 2;
      halign = TextField.H_LEFT;
    } else { // west or east
      y = isRectangular ? bds.getY() - 2 : bds.getY();
      if (control != null && control.getY() == bds.getY()) {
        // the control line will get in the way
        x = control.getX() + 2;
        halign = TextField.H_LEFT;
      } else {
        x = bds.getX() + bds.getWidth() / 2;
        halign = TextField.H_CENTER;
      }
    }
    instance.setTextField(StdAttr.LABEL, StdAttr.LABEL_FONT, x, y, halign, TextField.V_BASELINE);
  }
}
예제 #3
0
 @Override
 public Icon getIcon() {
   return Icons.getIcon("drawrrct.gif");
 }
예제 #4
0
public class SelectTool extends Tool {
  private static final Cursor selectCursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
  private static final Cursor rectSelectCursor =
      Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
  private static final Cursor moveCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);

  private static final int IDLE = 0;
  private static final int MOVING = 1;
  private static final int RECT_SELECT = 2;
  private static final Icon toolIcon = Icons.getIcon("select.gif");

  private static final Color COLOR_UNMATCHED = new Color(192, 0, 0);
  private static final Color COLOR_COMPUTING = new Color(96, 192, 96);
  private static final Color COLOR_RECT_SELECT = new Color(0, 64, 128, 255);
  private static final Color BACKGROUND_RECT_SELECT = new Color(192, 192, 255, 192);

  private static class MoveRequestHandler implements MoveRequestListener {
    private Canvas canvas;

    MoveRequestHandler(Canvas canvas) {
      this.canvas = canvas;
    }

    public void requestSatisfied(MoveGesture gesture, int dx, int dy) {
      clearCanvasMessage(canvas, dx, dy);
    }
  }

  private class Listener implements Selection.Listener {
    public void selectionChanged(Event event) {
      keyHandlers = null;
    }
  }

  private Location start;
  private int state;
  private int curDx;
  private int curDy;
  private boolean drawConnections;
  private MoveGesture moveGesture;
  private HashMap<Component, KeyConfigurator> keyHandlers;
  private HashSet<Selection> selectionsAdded;
  private Listener selListener;

  public SelectTool() {
    start = null;
    state = IDLE;
    selectionsAdded = new HashSet<Selection>();
    selListener = new Listener();
    keyHandlers = null;
  }

  @Override
  public boolean equals(Object other) {
    return other instanceof SelectTool;
  }

  @Override
  public int hashCode() {
    return SelectTool.class.hashCode();
  }

  @Override
  public String getName() {
    return "Select Tool";
  }

  @Override
  public String getDisplayName() {
    return Strings.get("selectTool");
  }

  @Override
  public String getDescription() {
    return Strings.get("selectToolDesc");
  }

  @Override
  public AttributeSet getAttributeSet(Canvas canvas) {
    return canvas.getSelection().getAttributeSet();
  }

  @Override
  public boolean isAllDefaultValues(AttributeSet attrs, LogisimVersion ver) {
    return true;
  }

  @Override
  public void draw(Canvas canvas, ComponentDrawContext context) {
    Project proj = canvas.getProject();
    int dx = curDx;
    int dy = curDy;
    if (state == MOVING) {
      proj.getSelection().drawGhostsShifted(context, dx, dy);

      MoveGesture gesture = moveGesture;
      if (gesture != null && drawConnections && (dx != 0 || dy != 0)) {
        MoveResult result = gesture.findResult(dx, dy);
        if (result != null) {
          Collection<Wire> wiresToAdd = result.getWiresToAdd();
          Graphics g = context.getGraphics();
          GraphicsUtil.switchToWidth(g, 3);
          g.setColor(Color.GRAY);
          for (Wire w : wiresToAdd) {
            Location loc0 = w.getEnd0();
            Location loc1 = w.getEnd1();
            g.drawLine(loc0.getX(), loc0.getY(), loc1.getX(), loc1.getY());
          }
          GraphicsUtil.switchToWidth(g, 1);
          g.setColor(COLOR_UNMATCHED);
          for (Location conn : result.getUnconnectedLocations()) {
            int connX = conn.getX();
            int connY = conn.getY();
            g.fillOval(connX - 3, connY - 3, 6, 6);
            g.fillOval(connX + dx - 3, connY + dy - 3, 6, 6);
          }
        }
      }
    } else if (state == RECT_SELECT) {
      int left = start.getX();
      int right = left + dx;
      if (left > right) {
        int i = left;
        left = right;
        right = i;
      }
      int top = start.getY();
      int bot = top + dy;
      if (top > bot) {
        int i = top;
        top = bot;
        bot = i;
      }

      Graphics gBase = context.getGraphics();
      int w = right - left - 1;
      int h = bot - top - 1;
      if (w > 2 && h > 2) {
        gBase.setColor(BACKGROUND_RECT_SELECT);
        gBase.fillRect(left + 1, top + 1, w - 1, h - 1);
      }

      Circuit circ = canvas.getCircuit();
      Bounds bds = Bounds.create(left, top, right - left, bot - top);
      for (Component c : circ.getAllWithin(bds)) {
        Location cloc = c.getLocation();
        Graphics gDup = gBase.create();
        context.setGraphics(gDup);
        c.getFactory()
            .drawGhost(context, COLOR_RECT_SELECT, cloc.getX(), cloc.getY(), c.getAttributeSet());
        gDup.dispose();
      }

      gBase.setColor(COLOR_RECT_SELECT);
      GraphicsUtil.switchToWidth(gBase, 2);
      if (w < 0) w = 0;
      if (h < 0) h = 0;
      gBase.drawRect(left, top, w, h);
    }
  }

  @Override
  public void select(Canvas canvas) {
    Selection sel = canvas.getSelection();
    if (!selectionsAdded.contains(sel)) {
      sel.addListener(selListener);
    }
  }

  @Override
  public void deselect(Canvas canvas) {
    moveGesture = null;
  }

  @Override
  public void mouseEntered(Canvas canvas, Graphics g, MouseEvent e) {
    canvas.requestFocusInWindow();
  }

  @Override
  public void mousePressed(Canvas canvas, Graphics g, MouseEvent e) {
    Project proj = canvas.getProject();
    Selection sel = proj.getSelection();
    Circuit circuit = canvas.getCircuit();
    start = Location.create(e.getX(), e.getY());
    curDx = 0;
    curDy = 0;
    moveGesture = null;

    // if the user clicks into the selection,
    // selection is being modified
    Collection<Component> in_sel = sel.getComponentsContaining(start, g);
    if (!in_sel.isEmpty()) {
      if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) {
        setState(proj, MOVING);
        proj.repaintCanvas();
        return;
      } else {
        Action act = SelectionActions.drop(sel, in_sel);
        if (act != null) {
          proj.doAction(act);
        }
      }
    }

    // if the user clicks into a component outside selection, user
    // wants to add/reset selection
    Collection<Component> clicked = circuit.getAllContaining(start, g);
    if (!clicked.isEmpty()) {
      if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) {
        if (sel.getComponentsContaining(start).isEmpty()) {
          Action act = SelectionActions.dropAll(sel);
          if (act != null) {
            proj.doAction(act);
          }
        }
      }
      for (Component comp : clicked) {
        if (!in_sel.contains(comp)) {
          sel.add(comp);
        }
      }
      setState(proj, MOVING);
      proj.repaintCanvas();
      return;
    }

    // The user clicked on the background. This is a rectangular
    // selection (maybe with the shift key down).
    if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) {
      Action act = SelectionActions.dropAll(sel);
      if (act != null) {
        proj.doAction(act);
      }
    }
    setState(proj, RECT_SELECT);
    proj.repaintCanvas();
  }

  @Override
  public void mouseDragged(Canvas canvas, Graphics g, MouseEvent e) {
    if (state == MOVING) {
      Project proj = canvas.getProject();
      computeDxDy(proj, e, g);
      handleMoveDrag(canvas, curDx, curDy, e.getModifiersEx());
    } else if (state == RECT_SELECT) {
      Project proj = canvas.getProject();
      curDx = e.getX() - start.getX();
      curDy = e.getY() - start.getY();
      proj.repaintCanvas();
    }
  }

  private void handleMoveDrag(Canvas canvas, int dx, int dy, int modsEx) {
    boolean connect = shouldConnect(canvas, modsEx);
    drawConnections = connect;
    if (connect) {
      MoveGesture gesture = moveGesture;
      if (gesture == null) {
        gesture =
            new MoveGesture(
                new MoveRequestHandler(canvas),
                canvas.getCircuit(),
                canvas.getSelection().getAnchoredComponents());
        moveGesture = gesture;
      }
      if (dx != 0 || dy != 0) {
        boolean queued = gesture.enqueueRequest(dx, dy);
        if (queued) {
          canvas.setErrorMessage(new ComputingMessage(dx, dy), COLOR_COMPUTING);
          // maybe CPU scheduled led the request to be satisfied
          // just before the "if(queued)" statement. In any case, it
          // doesn't hurt to check to ensure the message belongs.
          if (gesture.findResult(dx, dy) != null) {
            clearCanvasMessage(canvas, dx, dy);
          }
        }
      }
    }
    canvas.repaint();
  }

  private boolean shouldConnect(Canvas canvas, int modsEx) {
    boolean shiftReleased = (modsEx & MouseEvent.SHIFT_DOWN_MASK) == 0;
    boolean dflt = AppPreferences.MOVE_KEEP_CONNECT.getBoolean();
    if (shiftReleased) {
      return dflt;
    } else {
      return !dflt;
    }
  }

  @Override
  public void mouseReleased(Canvas canvas, Graphics g, MouseEvent e) {
    Project proj = canvas.getProject();
    if (state == MOVING) {
      setState(proj, IDLE);
      computeDxDy(proj, e, g);
      int dx = curDx;
      int dy = curDy;
      if (dx != 0 || dy != 0) {
        if (!proj.getLogisimFile().contains(canvas.getCircuit())) {
          canvas.setErrorMessage(Strings.getter("cannotModifyError"));
        } else if (proj.getSelection().hasConflictWhenMoved(dx, dy)) {
          canvas.setErrorMessage(Strings.getter("exclusiveError"));
        } else {
          boolean connect = shouldConnect(canvas, e.getModifiersEx());
          drawConnections = false;
          ReplacementMap repl;
          if (connect) {
            MoveGesture gesture = moveGesture;
            if (gesture == null) {
              gesture =
                  new MoveGesture(
                      new MoveRequestHandler(canvas),
                      canvas.getCircuit(),
                      canvas.getSelection().getAnchoredComponents());
            }
            canvas.setErrorMessage(new ComputingMessage(dx, dy), COLOR_COMPUTING);
            MoveResult result = gesture.forceRequest(dx, dy);
            clearCanvasMessage(canvas, dx, dy);
            repl = result.getReplacementMap();
          } else {
            repl = null;
          }
          Selection sel = proj.getSelection();
          proj.doAction(SelectionActions.translate(sel, dx, dy, repl));
        }
      }
      moveGesture = null;
      proj.repaintCanvas();
    } else if (state == RECT_SELECT) {
      Bounds bds = Bounds.create(start).add(start.getX() + curDx, start.getY() + curDy);
      Circuit circuit = canvas.getCircuit();
      Selection sel = proj.getSelection();
      Collection<Component> in_sel = sel.getComponentsWithin(bds, g);
      for (Component comp : circuit.getAllWithin(bds, g)) {
        if (!in_sel.contains(comp)) sel.add(comp);
      }
      Action act = SelectionActions.drop(sel, in_sel);
      if (act != null) {
        proj.doAction(act);
      }
      setState(proj, IDLE);
      proj.repaintCanvas();
    }
  }

  @Override
  public void keyPressed(Canvas canvas, KeyEvent e) {
    if (state == MOVING && e.getKeyCode() == KeyEvent.VK_SHIFT) {
      handleMoveDrag(canvas, curDx, curDy, e.getModifiersEx());
    } else {
      switch (e.getKeyCode()) {
        case KeyEvent.VK_BACK_SPACE:
        case KeyEvent.VK_DELETE:
          if (!canvas.getSelection().isEmpty()) {
            Action act = SelectionActions.clear(canvas.getSelection());
            canvas.getProject().doAction(act);
            e.consume();
          }
          break;
        default:
          processKeyEvent(canvas, e, KeyConfigurationEvent.KEY_PRESSED);
      }
    }
  }

  @Override
  public void keyReleased(Canvas canvas, KeyEvent e) {
    if (state == MOVING && e.getKeyCode() == KeyEvent.VK_SHIFT) {
      handleMoveDrag(canvas, curDx, curDy, e.getModifiersEx());
    } else {
      processKeyEvent(canvas, e, KeyConfigurationEvent.KEY_RELEASED);
    }
  }

  @Override
  public void keyTyped(Canvas canvas, KeyEvent e) {
    processKeyEvent(canvas, e, KeyConfigurationEvent.KEY_TYPED);
  }

  private void processKeyEvent(Canvas canvas, KeyEvent e, int type) {
    HashMap<Component, KeyConfigurator> handlers = keyHandlers;
    if (handlers == null) {
      handlers = new HashMap<Component, KeyConfigurator>();
      Selection sel = canvas.getSelection();
      for (Component comp : sel.getComponents()) {
        ComponentFactory factory = comp.getFactory();
        AttributeSet attrs = comp.getAttributeSet();
        Object handler = factory.getFeature(KeyConfigurator.class, attrs);
        if (handler != null) {
          KeyConfigurator base = (KeyConfigurator) handler;
          handlers.put(comp, base.clone());
        }
      }
      keyHandlers = handlers;
    }

    if (!handlers.isEmpty()) {
      boolean consume = false;
      ArrayList<KeyConfigurationResult> results;
      results = new ArrayList<KeyConfigurationResult>();
      for (Map.Entry<Component, KeyConfigurator> entry : handlers.entrySet()) {
        Component comp = entry.getKey();
        KeyConfigurator handler = entry.getValue();
        KeyConfigurationEvent event =
            new KeyConfigurationEvent(type, comp.getAttributeSet(), e, comp);
        KeyConfigurationResult result = handler.keyEventReceived(event);
        consume |= event.isConsumed();
        if (result != null) {
          results.add(result);
        }
      }
      if (consume) {
        e.consume();
      }
      if (!results.isEmpty()) {
        SetAttributeAction act =
            new SetAttributeAction(
                canvas.getCircuit(), Strings.getter("changeComponentAttributesAction"));
        for (KeyConfigurationResult result : results) {
          Component comp = (Component) result.getEvent().getData();
          Map<Attribute<?>, Object> newValues = result.getAttributeValues();
          for (Map.Entry<Attribute<?>, Object> entry : newValues.entrySet()) {
            act.set(comp, entry.getKey(), entry.getValue());
          }
        }
        if (!act.isEmpty()) {
          canvas.getProject().doAction(act);
        }
      }
    }
  }

  private void computeDxDy(Project proj, MouseEvent e, Graphics g) {
    Bounds bds = proj.getSelection().getBounds(g);
    int dx;
    int dy;
    if (bds == Bounds.EMPTY_BOUNDS) {
      dx = e.getX() - start.getX();
      dy = e.getY() - start.getY();
    } else {
      dx = Math.max(e.getX() - start.getX(), -bds.getX());
      dy = Math.max(e.getY() - start.getY(), -bds.getY());
    }

    Selection sel = proj.getSelection();
    if (sel.shouldSnap()) {
      dx = Canvas.snapXToGrid(dx);
      dy = Canvas.snapYToGrid(dy);
    }
    curDx = dx;
    curDy = dy;
  }

  @Override
  public void paintIcon(ComponentDrawContext c, int x, int y) {
    Graphics g = c.getGraphics();
    if (toolIcon != null) {
      toolIcon.paintIcon(c.getDestination(), g, x + 2, y + 2);
    } else {
      int[] xp = {x + 5, x + 5, x + 9, x + 12, x + 14, x + 11, x + 16};
      int[] yp = {y, y + 17, y + 12, y + 18, y + 18, y + 12, y + 12};
      g.setColor(java.awt.Color.black);
      g.fillPolygon(xp, yp, xp.length);
    }
  }

  @Override
  public Cursor getCursor() {
    return state == IDLE ? selectCursor : (state == RECT_SELECT ? rectSelectCursor : moveCursor);
  }

  @Override
  public Set<Component> getHiddenComponents(Canvas canvas) {
    if (state == MOVING) {
      int dx = curDx;
      int dy = curDy;
      if (dx == 0 && dy == 0) {
        return null;
      }

      Set<Component> sel = canvas.getSelection().getComponents();
      MoveGesture gesture = moveGesture;
      if (gesture != null && drawConnections) {
        MoveResult result = gesture.findResult(dx, dy);
        if (result != null) {
          HashSet<Component> ret = new HashSet<Component>(sel);
          ret.addAll(result.getReplacementMap().getRemovals());
          return ret;
        }
      }
      return sel;
    } else {
      return null;
    }
  }

  private void setState(Project proj, int new_state) {
    if (state == new_state) return; // do nothing if state not new

    state = new_state;
    proj.getFrame().getCanvas().setCursor(getCursor());
  }

  private static void clearCanvasMessage(Canvas canvas, int dx, int dy) {
    Object getter = canvas.getErrorMessage();
    if (getter instanceof ComputingMessage) {
      ComputingMessage msg = (ComputingMessage) getter;
      if (msg.dx == dx && msg.dy == dy) {
        canvas.setErrorMessage(null);
        canvas.repaint();
      }
    }
  }

  private static class ComputingMessage implements StringGetter {
    private int dx;
    private int dy;

    public ComputingMessage(int dx, int dy) {
      this.dx = dx;
      this.dy = dy;
    }

    public String get() {
      return Strings.get("moveWorkingMsg");
    }
  }
}
예제 #5
0
public class PullResistor extends InstanceFactory {
  public static final Attribute<AttributeOption> ATTR_PULL_TYPE =
      Attributes.forOption(
          "pull",
          Strings.getter("pullTypeAttr"),
          new AttributeOption[] {
            new AttributeOption(Value.FALSE, "0", Strings.getter("pullZeroType")),
            new AttributeOption(Value.TRUE, "1", Strings.getter("pullOneType")),
            new AttributeOption(Value.ERROR, "X", Strings.getter("pullErrorType"))
          });

  public static final PullResistor FACTORY = new PullResistor();

  private static final Icon ICON_SHAPED = Icons.getIcon("pullshap.gif");
  private static final Icon ICON_RECTANGULAR = Icons.getIcon("pullrect.gif");

  public PullResistor() {
    super("Pull Resistor", Strings.getter("pullComponent"));
    setAttributes(
        new Attribute[] {StdAttr.FACING, ATTR_PULL_TYPE},
        new Object[] {Direction.SOUTH, ATTR_PULL_TYPE.parse("0")});
    setFacingAttribute(StdAttr.FACING);
  }

  @Override
  public Bounds getOffsetBounds(AttributeSet attrs) {
    Direction facing = attrs.getValue(StdAttr.FACING);
    if (facing == Direction.EAST) {
      return Bounds.create(-42, -6, 42, 12);
    } else if (facing == Direction.WEST) {
      return Bounds.create(0, -6, 42, 12);
    } else if (facing == Direction.NORTH) {
      return Bounds.create(-6, 0, 12, 42);
    } else {
      return Bounds.create(-6, -42, 12, 42);
    }
  }

  //
  // graphics methods
  //
  @Override
  public void paintIcon(InstancePainter painter) {
    Icon icon;
    if (painter.getGateShape() == AppPreferences.SHAPE_SHAPED) {
      icon = ICON_SHAPED;
    } else {
      icon = ICON_RECTANGULAR;
    }
    icon.paintIcon(painter.getDestination(), painter.getGraphics(), 2, 2);
  }

  @Override
  public void paintGhost(InstancePainter painter) {
    Value pull = getPullValue(painter.getAttributeSet());
    paintBase(painter, pull, null, null);
  }

  @Override
  public void paintInstance(InstancePainter painter) {
    Location loc = painter.getLocation();
    int x = loc.getX();
    int y = loc.getY();
    Graphics g = painter.getGraphics();
    g.translate(x, y);
    Value pull = getPullValue(painter.getAttributeSet());
    Value actual = painter.getPort(0);
    paintBase(painter, pull, pull.getColor(), actual.getColor());
    g.translate(-x, -y);
    painter.drawPorts();
  }

  private void paintBase(InstancePainter painter, Value pullValue, Color inColor, Color outColor) {
    boolean color = painter.shouldDrawColor();
    Direction facing = painter.getAttributeValue(StdAttr.FACING);
    Graphics g = painter.getGraphics();
    Color baseColor = g.getColor();
    GraphicsUtil.switchToWidth(g, 3);
    if (color && inColor != null) g.setColor(inColor);
    if (facing == Direction.EAST) {
      GraphicsUtil.drawText(
          g, pullValue.toDisplayString(), -32, 0, GraphicsUtil.H_RIGHT, GraphicsUtil.V_CENTER);
    } else if (facing == Direction.WEST) {
      GraphicsUtil.drawText(
          g, pullValue.toDisplayString(), 32, 0, GraphicsUtil.H_LEFT, GraphicsUtil.V_CENTER);
    } else if (facing == Direction.NORTH) {
      GraphicsUtil.drawText(
          g, pullValue.toDisplayString(), 0, 32, GraphicsUtil.H_CENTER, GraphicsUtil.V_TOP);
    } else {
      GraphicsUtil.drawText(
          g, pullValue.toDisplayString(), 0, -32, GraphicsUtil.H_CENTER, GraphicsUtil.V_BASELINE);
    }

    double rotate = 0.0;
    if (g instanceof Graphics2D) {
      rotate = Direction.SOUTH.toRadians() - facing.toRadians();
      if (rotate != 0.0) ((Graphics2D) g).rotate(rotate);
    }
    g.drawLine(0, -30, 0, -26);
    g.drawLine(-6, -30, 6, -30);
    if (color && outColor != null) g.setColor(outColor);
    g.drawLine(0, -4, 0, 0);
    g.setColor(baseColor);
    GraphicsUtil.switchToWidth(g, 2);
    if (painter.getGateShape() == AppPreferences.SHAPE_SHAPED) {
      int[] xp = {0, -5, 5, -5, 5, -5, 0};
      int[] yp = {-25, -23, -19, -15, -11, -7, -5};
      g.drawPolyline(xp, yp, xp.length);
    } else {
      g.drawRect(-5, -25, 10, 20);
    }
    if (rotate != 0.0) {
      ((Graphics2D) g).rotate(-rotate);
    }
  }

  //
  // methods for instances
  //
  @Override
  protected void configureNewInstance(Instance instance) {
    instance.addAttributeListener();
    instance.setPorts(new Port[] {new Port(0, 0, Port.INOUT, BitWidth.UNKNOWN)});
  }

  @Override
  protected void instanceAttributeChanged(Instance instance, Attribute<?> attr) {
    if (attr == StdAttr.FACING) {
      instance.recomputeBounds();
    } else if (attr == ATTR_PULL_TYPE) {
      instance.fireInvalidated();
    }
  }

  @Override
  public void propagate(InstanceState state) {
    ; // nothing to do - handled by CircuitWires
  }

  public static Value getPullValue(Instance instance) {
    return getPullValue(instance.getAttributeSet());
  }

  private static Value getPullValue(AttributeSet attrs) {
    AttributeOption opt = attrs.getValue(ATTR_PULL_TYPE);
    return (Value) opt.getValue();
  }
}