/*******************************************************************************
* This file is part of logisim-evolution.
*
* logisim-evolution is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* logisim-evolution is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with logisim-evolution. If not, see <http://www.gnu.org/licenses/>.
*
* Original code by Carl Burch (http://www.cburch.com), 2011.
* Subsequent modifications by :
* + Haute École Spécialisée Bernoise
* http://www.bfh.ch
* + Haute École du paysage, d'ingénierie et d'architecture de Genève
* http://hepia.hesge.ch/
* + Haute École d'Ingénierie et de Gestion du Canton de Vaud
* http://www.heig-vd.ch/
* The project is currently maintained by :
* + REDS Institute - HEIG-VD
* Yverdon-les-Bains, Switzerland
* http://reds.heig-vd.ch
*******************************************************************************/
package com.cburch.logisim.gui.start;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import com.cburch.logisim.Main;
import com.cburch.logisim.data.Value;
import com.cburch.logisim.util.GraphicsUtil;
public class About {
private static class MyPanel extends JPanel implements AncestorListener {
private static int toDim(int offs) {
return offs * 3 / 2;
}
private static int toX(int x0, int offs) {
return x0 + offs * 3 / 2;
}
private static int toY(int y0, int offs) {
return y0 + offs * 3 / 2;
}
private static final long serialVersionUID = 1L;
private final Color fadeColor = new Color(255, 255, 255, 128);
private final Color headerColor = new Color(143, 0, 0);
private final Color gateColor = Color.DARK_GRAY;
private final Font headerFont = new Font("Monospaced", Font.BOLD, 34);
private final Font versionFont = new Font("Serif", Font.PLAIN
| Font.ITALIC, 20);
private final Font copyrightFont = new Font("Serif", Font.ITALIC, 12);
private Value upper = Value.FALSE;
private Value lower = Value.TRUE;
private AboutCredits credits;
private PanelThread thread = null;
public MyPanel() {
setLayout(null);
int prefWidth = IMAGE_WIDTH + 2 * IMAGE_BORDER;
int prefHeight = IMAGE_HEIGHT + 2 * IMAGE_BORDER;
setPreferredSize(new Dimension(prefWidth, prefHeight));
setBackground(Color.WHITE);
addAncestorListener(this);
credits = new AboutCredits();
credits.setBounds(0, prefHeight / 2, prefWidth, prefHeight / 2);
add(credits);
}
public void ancestorAdded(AncestorEvent arg0) {
if (thread == null) {
thread = new PanelThread(this);
thread.start();
}
}
public void ancestorMoved(AncestorEvent arg0) {
}
public void ancestorRemoved(AncestorEvent arg0) {
if (thread != null) {
thread.running = false;
}
}
private void drawAnd(Graphics g, int x0, int y0, int x, int y) {
int[] xp = new int[4];
int[] yp = new int[4];
xp[0] = toX(x0, x - 25);
yp[0] = toY(y0, y - 25);
xp[1] = toX(x0, x - 50);
yp[1] = yp[0];
xp[2] = xp[1];
yp[2] = toY(y0, y + 25);
xp[3] = xp[0];
yp[3] = yp[2];
int diam = toDim(50);
g.drawArc(xp[1], yp[1], diam, diam, -90, 180);
g.drawPolyline(xp, yp, 4);
}
private void drawCircuit(Graphics g, int x0, int y0) {
if (g instanceof Graphics2D) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(5.0f));
}
drawWires(g, x0, y0);
g.setColor(gateColor);
drawNot(g, x0, y0, 70, 10);
drawNot(g, x0, y0, 70, 110);
drawAnd(g, x0, y0, 130, 30);
drawAnd(g, x0, y0, 130, 90);
drawOr(g, x0, y0, 220, 60);
}
private void drawNot(Graphics g, int x0, int y0, int x, int y) {
int[] xp = new int[4];
int[] yp = new int[4];
xp[0] = toX(x0, x - 10);
yp[0] = toY(y0, y);
xp[1] = toX(x0, x - 29);
yp[1] = toY(y0, y - 7);
xp[2] = xp[1];
yp[2] = toY(y0, y + 7);
xp[3] = xp[0];
yp[3] = yp[0];
g.drawPolyline(xp, yp, 4);
int diam = toDim(10);
g.drawOval(xp[0], yp[0] - diam / 2, diam, diam);
}
private void drawOr(Graphics g, int x0, int y0, int x, int y) {
int cx = toX(x0, x - 50);
int cd = toDim(62);
GraphicsUtil.drawCenteredArc(g, cx, toY(y0, y - 37), cd, -90, 53);
GraphicsUtil.drawCenteredArc(g, cx, toY(y0, y + 37), cd, 90, -53);
GraphicsUtil.drawCenteredArc(g, toX(x0, x - 93), toY(y0, y),
toDim(50), -30, 60);
}
private void drawText(Graphics g, int x, int y) {
FontMetrics fm;
String str;
g.setColor(headerColor);
g.setFont(headerFont);
g.drawString("Logisim-evolution", x, y + 25);
g.setFont(copyrightFont);
fm = g.getFontMetrics();
str = "\u00a9 " + Main.COPYRIGHT_YEAR;
g.drawString(str, x + IMAGE_WIDTH - fm.stringWidth(str), y + 12);
str = "HES-SO";
g.drawString(str, x + IMAGE_WIDTH - fm.stringWidth(str), y + 26);
g.setFont(versionFont);
fm = g.getFontMetrics();
str = "Version " + Main.VERSION.mainVersion();
g.drawString(str, x + IMAGE_WIDTH - fm.stringWidth(str), y + 50);
g.setFont(copyrightFont);
fm = g.getFontMetrics();
str = Main.VERSION.rev();
g.drawString(str, x + IMAGE_WIDTH - fm.stringWidth(str), y + 50);
}
private void drawWires(Graphics g, int x0, int y0) {
Value upperNot = upper.not();
Value lowerNot = lower.not();
Value upperAnd = upperNot.and(lower);
Value lowerAnd = lowerNot.and(upper);
Value out = upperAnd.or(lowerAnd);
int x;
int y;
g.setColor(upper.getColor());
x = toX(x0, 20);
y = toY(y0, 10);
g.fillOval(x - 7, y - 7, 14, 14);
g.drawLine(toX(x0, 0), y, toX(x0, 40), y);
g.drawLine(x, y, x, toY(y0, 70));
y = toY(y0, 70);
g.drawLine(x, y, toX(x0, 80), y);
g.setColor(upperNot.getColor());
y = toY(y0, 10);
g.drawLine(toX(x0, 70), y, toX(x0, 80), y);
g.setColor(lower.getColor());
x = toX(x0, 30);
y = toY(y0, 110);
g.fillOval(x - 7, y - 7, 14, 14);
g.drawLine(toX(x0, 0), y, toX(x0, 40), y);
g.drawLine(x, y, x, toY(y0, 50));
y = toY(y0, 50);
g.drawLine(x, y, toX(x0, 80), y);
g.setColor(lowerNot.getColor());
y = toY(y0, 110);
g.drawLine(toX(x0, 70), y, toX(x0, 80), y);
g.setColor(upperAnd.getColor());
x = toX(x0, 150);
y = toY(y0, 30);
g.drawLine(toX(x0, 130), y, x, y);
g.drawLine(x, y, x, toY(y0, 45));
y = toY(y0, 45);
g.drawLine(x, y, toX(x0, 174), y);
g.setColor(lowerAnd.getColor());
y = toY(y0, 90);
g.drawLine(toX(x0, 130), y, x, y);
g.drawLine(x, y, x, toY(y0, 75));
y = toY(y0, 75);
g.drawLine(x, y, toX(x0, 174), y);
g.setColor(out.getColor());
y = toY(y0, 60);
g.drawLine(toX(x0, 220), y, toX(x0, 240), y);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
try {
int x = IMAGE_BORDER;
int y = IMAGE_BORDER;
drawCircuit(g, x + 10, y + 55);
g.setColor(fadeColor);
g.fillRect(x, y, IMAGE_WIDTH, IMAGE_HEIGHT);
drawText(g, x, y);
} catch (Throwable t) {
}
}
}
private static class PanelThread extends Thread {
private MyPanel panel;
private boolean running = true;
PanelThread(MyPanel panel) {
this.panel = panel;
}
@Override
public void run() {
long start = System.currentTimeMillis();
while (running) {
long elapse = System.currentTimeMillis() - start;
int count = (int) (elapse / 500) % 4;
panel.upper = (count == 2 || count == 3) ? Value.TRUE
: Value.FALSE;
panel.lower = (count == 1 || count == 2) ? Value.TRUE
: Value.FALSE;
panel.credits.setScroll((int) elapse);
panel.repaint();
try {
Thread.sleep(20);
} catch (InterruptedException ex) {
}
}
}
}
public static MyPanel getImagePanel() {
return new MyPanel();
}
public static void showAboutDialog(JFrame owner) {
MyPanel imgPanel = getImagePanel();
JPanel panel = new JPanel(new BorderLayout());
panel.add(imgPanel);
panel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
JOptionPane.showMessageDialog(owner, panel, "Logisim-evolution "
+ Main.VERSION_NAME, JOptionPane.PLAIN_MESSAGE);
}
static final int IMAGE_BORDER = 30;
static final int IMAGE_WIDTH = 430;
static final int IMAGE_HEIGHT = 284;
private About() {
}
}