You are on page 1of 6

/*

* Copyright (c) 2009 Robert Esser


*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.e2ser.component;
import java.io.IOException;
import java.util.ArrayList;
import
import
import
import
import
import
import
import

net.e2ser.petri.Color;
net.e2ser.petri.Editor;
net.e2ser.petri.RobPoint;
net.e2ser.petri.SimulatorMode;
net.e2ser.util.XMLWriter;
android.graphics.Canvas;
android.graphics.Rect;
android.graphics.drawable.ShapeDrawable;

/**
*
* <p>Title: Petri Net Editor/Simulator</p>
* <p>Description: A 2D node class</p>
* <p>Copyright: Copyright (c) 2009</p>
* <p>Company: </p>
* @author Rob Esser
* @version 1.0
*/
abstract public class AbstractComponent extends AbstractElement {
private static final ArrayList<AbstractComponent> EMPTYLIST = new ArrayList<Ab
stractComponent>();
private static final int DefaultComponentWidth = 20;
private static final int DefaultComponentHeight = 20;
private Rect componentBounds;
private float textSize = 6.0f;
protected ShapeDrawable shape;
protected String name = null; // the name of the element
protected boolean inverse = false;
public RobComponent parent = null;
protected int fillColor = Color.GRAY;
public AbstractComponent(RobComponent parent, int x, int y) {
this.parent = parent;
componentBounds = new Rect(x, y, x + DefaultComponentWidth, y + DefaultCompo
nentHeight);
}

public AbstractComponent(RobComponent parent, int x, int y, int width, int hei


ght) {
this.parent = parent;
componentBounds = new Rect(x, y, x + width, y + height);
}
/**
* return the current default width of the component
* @return int
*/
public static int DefaultComponentWidth() {
return DefaultComponentWidth;
}
/**
* return the current default height of the component
* @return int
*/
public static int DefaultComponentHeight() {
return DefaultComponentHeight;
}
public Rect getComponentBounds() {
return componentBounds;
}
public float textSize() {
return textSize;
}
public void recalulateTextSize() {
textSize = (float) (shape.getBounds().height() / 3.0);
shape.getPaint().setTextSize(textSize);
}
public void resize(double scale) {
Rect r = new Rect(componentBounds);
r.left *= scale;
r.right *= scale;
r.top *= scale;
r.bottom *= scale;
shape.setBounds(r);
recalulateTextSize();
}
/**
* if fireable add myself to fireList
* @param fireList Vector
* @param mode SimulatorMode
*/
abstract void addFireable(ArrayList<AbstractComponent> fireList, SimulatorMode
mode);
/**
* notify my observers that my child comp has changed
* @param comp AbstractComponent
*/
public void changed(AbstractComponent comp) {
parent.changed(comp);
}

/**
* make myself noticeable
* @param delay int
*/
public void blink(int delay) {
// force myself to blink
inverse = true;
parent.changed(this);
if (delay > 0) {
try {Thread.sleep(delay);
} catch (InterruptedException e) {}
} else {
//invalid delay setting
}
inverse = false;
parent.changed(this);
}
/**
* add a token - default do nothing
*/
public void addToken() {
}
/**
* remove a token - default do nothing
*/
public void removeToken() {
}
/**
* fire the node - by default do nothing
* @param mode SimulatorMode
* @param animation boolean
* @param delay int
*/
public void fire(SimulatorMode mode, boolean animation, int delay) {
}
/**
* draw myself on the Canvas
* @param canvas where to draw
*/
abstract public void draw(Canvas canvas);
/**
* Draw a marker to indicate that the node is selected
* @param canvas where to draw
*/
public void drawSelected(Canvas canvas) {
Rect r = new Rect(shape.getBounds());
shape.getPaint().setColor(Color.darker(Color.darker(fillColor)));
r.inset(r.width() / 3, r.height() / 3);
canvas.drawRect(r, shape.getPaint());
}
/**
* return a point on my circumference to which an arc is joined
* @param otherEnd RobPoint

* @return RobPoint
*/
abstract RobPoint connectionPoint(RobPoint otherEnd);
/**
* Return the top of this hierarchy
* @return RobComponent
*/
public RobComponent topNode() {
// return the root node
return parent.topNode();
}
/**
* Can a conection from node be connected to me?
* @param node AbstractComponent
* @return boolean
*/
public boolean canAddConnection(AbstractComponent node) {
// can always start a connection from me
return true;
}
/**
* Only can add a connection if nodes are of different classes!
* @param node1 AbstractComponent
* @param node2 AbstractComponent
* @return boolean
*/
public boolean canAddConnection(AbstractComponent node1, AbstractComponent nod
e2) {
return !node1.getClass().equals(node2.getClass());
}
/**
* Move the node origin
* @param x double
* @param y double
*/
public void move(double x, double y) {
Rect r = shape.getBounds();
int newX = Math.max((int) x, 0);
int newY = Math.max((int) y, 0);
r.offsetTo(newX, newY);
shape.setBounds(r);
componentBounds.offsetTo((int) (newX / Editor.DisplayScale), (int) (ne
wY / Editor.DisplayScale));
}
/**
* does my shape contain the point
* @param x int
* @param y int
* @return boolean
*/
public boolean contains(int x, int y) {
return shape.getBounds().contains(x, y);
}
/**

* the inside shape


* @return Rectangle
*/
public Rect bounds() {
return shape.getBounds();
}
/**
* Return the origin of my shape
* @return RobPoint
*/
public RobPoint origin() {
return new RobPoint(shape.getBounds().left, shape.getBounds().top);
}
/**
* Return the center of the shape
* @return RobPoint
*/
public RobPoint center() {
return new RobPoint(shape.getBounds().centerX(), shape.getBounds().centerY()
);
}
/**
* insert a new NodeInstance in parent
* @param parent RobComponent
* @param x int
* @param y int
* @return AbstractComponent
*/
abstract public AbstractComponent insertElementIn(RobComponent parent, int x,
int y, double scale);
/**
* return all input of ele
* @param ele AbstractComponent
* @return Vector
*/
public ArrayList<AbstractComponent> allInputs(AbstractComponent ele) {
return EMPTYLIST;
}
/**
* return all output of ele
* @param ele AbstractComponent
* @return Vector
*/
public ArrayList<AbstractComponent> allOutputs(AbstractComponent ele) {
return EMPTYLIST;
}
/**
* return all output of ele that are not also inputs
* @param ele AbstractComponent
* @return Vector
*/
public ArrayList<AbstractComponent> onlyOutputs(AbstractComponent ele) {

return EMPTYLIST;
}
/**
* return all inputs of myself
* @return Vector
*/
public ArrayList<AbstractComponent> allInputs() {
return parent.allInputs(this);
}
/**
* return all outputs of myself
* @return Vector
*/
public ArrayList<AbstractComponent> allOutputs() {
return parent.allOutputs(this);
}
/**
* return all outputs of myself that are not also inputs
* @return Vector
*/
public ArrayList<AbstractComponent> onlyOutputs() {
return parent.onlyOutputs(this);
}
public int componentWidth() {
return componentBounds.width();
}
public int componentHeight() {
return componentBounds.height();
}
/**
* Output an XML representation of myself
* @param writer object that represents writer state
* @throws IOException
*/
abstract public void toXML(XMLWriter writer) throws IOException;
}

You might also like