Ciąg dalszy implementacji klas.
Implementacja klasy Wire
package com.adam_mistal.logicgateapp; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; public class Wire { //Pin wysyłający sygnał i odbierający private Pin pin_one; private Pin pin_two; private Paint wireBrush = null; private int WireWidth=10; private float[] pts; public Wire(Pin pin1,Pin pin2){ pin_one=pin1; pin_two=pin2; if(pin_one.isMaster){ //pin pierwszy podaje sygnał pin_one.refPin=pin_two; }; if(pin_two.isMaster){ //pin drugi podaje sygnał pin_two.refPin=pin_one; }; wireBrush = new Paint(); wireBrush.setColor(Color.RED); wireBrush.setDither(true); wireBrush.setAlpha(150); wireBrush.setStrokeWidth(WireWidth); parse(pin_one.getPoint(), pin_two.getPoint()); } /** * rysuje przewód * @param canvas */ public void draw(Canvas canvas){ canvas.drawLines(pts, wireBrush); } /** * rysuje linie miedzy pinami w ten sposób aby załąmanie lini było prostopadłe * @param p1 * @param p2 */ private void parse(Point p1,Point p2){ Point n; if(p1.x!=p2.x){ n=new Point(p2.x, p1.y); pts=new float[8]; pts[0]=p1.x; pts[1]=p1.y; pts[2]=n.x; pts[3]=n.y; pts[4]=n.x; pts[5]=n.y; pts[6]=p2.x; pts[7]=p2.y; }else{ pts=new float[4]; pts[0]=p1.x; pts[1]=p1.y; pts[2]=p2.x; pts[3]=p2.y; } } }
Implementacja klasy OnOffButton
package com.adam_mistal.logicgateapp; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.Log; public class OnOffButton { public static int Width = 80; public int Height = 80; private String Text = "Off"; private int TextSize=50; private int colorOn=Color.GREEN; private int colorOff=Color.GRAY; private int Left = 0; private int Top = 0; private int Right=0; private int Bootom=0; private int textX,textY; private boolean isOn=false; private Paint paintBrush = null; private Paint textBrush = null; private Pin pin=null; public OnOffButton() { paintBrush = new Paint(); paintBrush.setColor(colorOff); paintBrush.setAntiAlias(true); paintBrush.setDither(true); textBrush = new Paint(); textBrush.setColor(Color.BLACK); textBrush.setAntiAlias(true); textBrush.setDither(true); textBrush.setTextSize(TextSize); setTopPin(); } public void draw(Canvas canvas) { canvas.drawRect(Left, Top, Right, Bootom, paintBrush); canvas.drawText(Text, textX, textY, textBrush); pin.draw(canvas); } /* * usatwiam pin na górze elementu */ public void setTopPin(){ pin =new Pin(true); pin.setCenter(Left+Width/2, Top-Pin.Height); } public void checkIfClicked(Point clickPoint){ //sprawdzam czy kliknięto przycisk if(Tools.checkIfClickedInRect(clickPoint, Left, Right, Bootom, Top)){ onTouch(); } } private void onTouch() { //usatwieni pinów if(isOn){ paintBrush.setColor(colorOff); pin.setValue(false); pin.refPin.setValue(false); Text = "Off"; isOn=false; }else{ paintBrush.setColor(colorOn); pin.setValue(true); pin.refPin.setValue(true); Text = "On"; isOn=true; } Log.i("OnOffButton", "ison?"+isOn); } public void setRight(int r) { Right=r; Left=r-Width; textX=Left+5; setTopPin(); } public void setLeft(int l) { Left=l; Right=l+Width; textX=Left+5; setTopPin(); } public void setTop(int t) { Top=t; Bootom=t+Height; textY=Top+Width/2; setTopPin(); } public Pin getPin() { return pin; } }
Implementacja klasy Tools
package com.adam_mistal.logicgateapp; public class Tools { //zwraca długość pomiędzy punktami public static double getLength2D(Point p1,Point p2){ double sdx=p2.x-p1.x; double sdy=p2.y-p1.y; double slength2D=Math.sqrt(Math.pow(sdx, 2)+Math.pow(sdy, 2)); return slength2D; } //zwraca true jeśli kliknięto w podany region public static boolean checkIfClickedInRect(Point p,int left,int right,int bootom,int top){ double testX=p.x; double testY=p.y; if(testX>left&&testX<right) if(testY>top&&testY<bootom){ return true; } return false; } }
Implementacja klasy Lamp
package com.adam_mistal.logicgateapp; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; public class Lamp { private int centerW=0; private int centerH=0; private int radius=40; private Paint paintBrush = null; private Pin pin=null; public Lamp(){ pin=new Pin(false); paintBrush = new Paint(); paintBrush.setColor(Color.GREEN); paintBrush.setAntiAlias(true); paintBrush.setDither(true); } public void draw(Canvas canvas) { updatePin(); canvas.drawCircle(centerW, centerH, radius, paintBrush); pin.draw(canvas); } private void updatePin() { if(pin.value){ switchOn(); }else{ switchOff(); } } public void setCenter(int cW, int cH) { centerH=cH; centerW=cW; pin.setCenter(cW, cH+radius); } public void setRadius(int i) { radius=i; } private void switchOn(){ paintBrush.setColor(Color.YELLOW); } private void switchOff(){ paintBrush.setColor(Color.GRAY); } public Point getCenter() { return new Point(centerW, centerH); } public Pin getPin() { return pin; } }
Utworzenie klasy Gate będącej klasą bazową dla szczególnych bramek logicznych
package com.adam_mistal.logicgateapp; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; public abstract class Gate{ protected int center_Y; protected int center_X; protected int left; protected int right; protected int top; protected int bottom; private Paint paintBrush = null; private Paint textBrush = null; protected Pin[] in_pins; protected int in_pin_count=0; private int pins=0; protected Pin outPin=null; protected Path path; private int TextSize; private int textX; private int textY; protected String gate_name="Gate"; public Gate() { paintBrush = new Paint(); setColor(Color.BLUE, 150); setTextColor(Color.YELLOW); setTextSize(40); path=new Path(); outPin=new Pin(true); } protected void setText(String t){ gate_name=t; } public void setTextSize(int i) { TextSize=i; textBrush.setTextSize(TextSize); } public void setTextColor(int col) { textBrush = new Paint(); textBrush.setColor(col); textBrush.setAntiAlias(true); textBrush.setDither(true); } public void setColor(int color,int alfa){ paintBrush.setColor(color); paintBrush.setAlpha(alfa); paintBrush.setStyle(Paint.Style.FILL_AND_STROKE); paintBrush.setStrokeWidth(2); } public void draw(Canvas canvas) { updateOutPin(); canvas.drawPath(path, paintBrush); draw_in_pins(canvas); outPin.draw(canvas); drawGateNAme(canvas); } private void drawGateNAme(Canvas canvas) { canvas.drawText(gate_name, textX, textY, textBrush); } private void draw_in_pins(Canvas canvas) { for(Pin p:in_pins){ p.draw(canvas); } } /** * W tej metodzie musimy zaimplementować rysowanie naszych bramek logicznych * @param c_x * @param c_y */ abstract protected void makeUI(int c_x,int c_y); /** * W tej metodzie zaimplementujemy obliczenia które ma realizować bramka */ abstract protected void updateOutPin(); /** * Ustawienie bramki tak by miała dwa wejścia */ protected void setTwoInputGate(){ in_pin_count=2; in_pins=new Pin[in_pin_count]; addPin(new Pin(false)); addPin(new Pin(false)); } /** * Ustawienie bramki tak by miała jedno wejście */ protected void setOneInputGate(){ in_pin_count=1; in_pins=new Pin[in_pin_count]; addPin(new Pin(false)); } /** * dodanie pinu * @param p */ private void addPin(Pin p) { if(pins<in_pin_count){ in_pins[pins++]=p; } } public void setCenter(int x, int y) { makeUI(x, y); setUpPins(); setTextPosCenter(); } public void setTextPos(int x, int y) { textX=x; textY=y; } public void setTextPosCenter(){ Paint paint = new Paint(); paint.setTextSize(TextSize); float w=paint.measureText(gate_name); textX=(int) (center_X-w/2); textY=center_Y; } /** * Usatwienia pinów */ private void setUpPins() { int width = right - left - 2 * Pin.Width; if (in_pin_count == 2) { int offset = width / (in_pin_count - 1); int i = 0; int l = left + Pin.Width; for (Pin p : in_pins) { p.setCenter(l + i, bottom); i += offset; } }else{ in_pins[0].setCenter(center_X, bottom); } outPin.setCenter(center_X, top - Pin.Height); } public int getTop() { return top; } public int getLeft() { return left; } public int getBottom() { return bottom; } public int getRight() { return right; } public Pin getOutPin() { return outPin; } public Pin getInPin(int nr) { return in_pins[nr]; } public int getPinCount(){ return in_pin_count; } }
Klasa Gate jest abstrakcyjna, czyli nie można tworzyć obiektów jej klasy.Wykorzystamy ją do dziedziczenia na klasy AndGate,OrGate itd.
Klasa AndGate
package com.adam_mistal.logicgateapp; import android.graphics.RectF; import android.graphics.Path.Direction; public class AndGate extends Gate { static public final String[] TRUE_TABLE={"X1","X2","Y", "0","0","0", "0","1","0", "1","0","0", "1","1","1", }; public AndGate(){ //usawiamy jako dwuwejsciowa setTwoInputGate(); setText("AND"); } @Override protected void makeUI(int c_x, int c_y) { int radius; int half_width=50; radius=half_width; int half_height=50; this.center_Y=c_y; this.center_X=c_x; left = center_X - half_width; right = center_X+ half_width; top = center_Y -half_height-radius; bottom = center_Y + half_height; //rysujemy nasza bramkę path.addRect(new RectF(left, top+radius, right, bottom),Direction.CW); path.moveTo(left, top+radius); path.lineTo(center_X, top); path.lineTo(right, top+radius); path.addArc(new RectF(left, top, right, top+2*radius), 180f, 90f); path.addArc(new RectF(left, top, right, top+2*radius), 270f, 90f); path.close(); } @Override protected void updateOutPin() { //tu własnie następuje ustawienie wyjściowego pinu na podstawie wejściowych pinów if(in_pins[0].value && in_pins[1].value){ outPin.setValue(true); }else{ outPin.setValue(false); } } }
Klasa NandGate
package com.adam_mistal.logicgateapp; import android.graphics.RectF; import android.graphics.Path.Direction; public class NandGate extends Gate { static public final String[] TRUE_TABLE={"X1","X2","Y", "0","0","1", "0","1","1", "1","0","1", "1","1","0", }; public NandGate(){ setTwoInputGate(); setText("NAND"); } @Override protected void makeUI(int c_x, int c_y) { int radius; int half_width=50; radius=half_width; int radius2=radius/3; int half_height=50; this.center_Y=c_y; this.center_X=c_x; left = center_X - half_width; right = center_X+ half_width; top = center_Y -half_height-radius-2*radius2; bottom = center_Y + half_height; path.addRect(new RectF(left, top+radius+2*radius2, right, bottom),Direction.CW); path.moveTo(left, top+radius+2*radius2); path.lineTo(center_X, top+2*radius2); path.lineTo(right, top+radius+2*radius2); path.addArc(new RectF(left, top+2*radius2, right, top+2*radius+2*radius2), 180f, 90f); path.addArc(new RectF(left, top+2*radius2, right, top+2*radius+2*radius2), 270f, 90f); path.addCircle(center_X, top+radius2, radius2,Direction.CW); path.close(); } @Override protected void updateOutPin() { if(in_pins[0].value && in_pins[1].value){ outPin.setValue(false); }else{ outPin.setValue(true); } } }
Klasa OrGate
package com.adam_mistal.logicgateapp; import android.graphics.RectF; import android.graphics.Path.Direction; public class OrGate extends Gate { static public final String[] TRUE_TABLE={"X1","X2","Y", "0","0","0", "0","1","1", "1","0","1", "1","1","1", }; public OrGate() { setTwoInputGate(); setText("OR"); } protected void updateOutPin() { if(in_pins[0].value || in_pins[1].value){ outPin.setValue(true); }else{ outPin.setValue(false); } } @Override protected void makeUI(int c_x, int c_y) { int radius; int half_width=50; radius=90; int half_height=50; this.center_Y=c_y; this.center_X=c_x; left = center_X - half_width; right = center_X+ half_width; top = center_Y -half_height-radius; bottom = center_Y + half_height; path.addRect(new RectF(left, top+radius, right, bottom),Direction.CW); path.moveTo(left, top+radius); path.lineTo(center_X, top); path.lineTo(right, top+radius); path.addArc(new RectF(left, top, right, top+2*radius), 180f, 90f); path.addArc(new RectF(left, top, right, top+2*radius), 270f, 90f); path.addArc(new RectF(left, top, right, top+2*radius), 270f, 90f); path.close(); } }
Klasa XorGate
package com.adam_mistal.logicgateapp; import android.graphics.RectF; import android.graphics.Path.Direction; public class XorGate extends Gate { static public final String[] TRUE_TABLE={"X1","X2","Y", "0","0","0", "0","1","1", "1","0","1", "1","1","0", }; public XorGate(){ setTwoInputGate(); setText("XOR"); } @Override protected void makeUI(int c_x, int c_y) { int radius; int half_width=50; radius=half_width; int half_height=50; this.center_Y=c_y; this.center_X=c_x; left = center_X - half_width; right = center_X+ half_width; top = center_Y -half_height-radius; bottom = center_Y + half_height; path.addRect(new RectF(left, top+radius, right, bottom),Direction.CW); path.moveTo(left, top+radius); path.lineTo(center_X, top); path.lineTo(right, top+radius); path.addArc(new RectF(left, top, right, top+2*radius), 180f, 90f); path.addArc(new RectF(left, top, right, top+2*radius), 270f, 90f); path.close(); } @Override protected void updateOutPin() { if(in_pins[0].value != in_pins[1].value){ outPin.setValue(true); }else{ outPin.setValue(false); } } }
Klasa Grid
package com.adam_mistal.logicgateapp; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; //klasa bedzie wyswietlac linie pionowa i poziomą public class Grid { private int width=60; private int height=60; private Paint paintBrushBlue = null; private Paint paintBrushGreen = null; public Grid(int w, int h) { width=w; height=h; paintBrushBlue = new Paint(); paintBrushBlue.setColor(Color.BLUE); paintBrushGreen = new Paint(); paintBrushGreen.setColor(Color.WHITE); paintBrushBlue.setAntiAlias(true); paintBrushBlue.setDither(true); paintBrushGreen.setAntiAlias(true); paintBrushGreen.setDither(true); } public void draw(Canvas canvas) { canvas.drawLine(width/2, 0, width/2, height, paintBrushGreen); canvas.drawLine(0, height/2, width, height/2, paintBrushGreen); } }