Package com.cburch.logisim.gui.main

Source Code of com.cburch.logisim.gui.main.CanvasPainter

/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */

package com.cburch.logisim.gui.main;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collections;
import java.util.Set;

import com.cburch.logisim.circuit.Circuit;
import com.cburch.logisim.circuit.CircuitState;
import com.cburch.logisim.circuit.WidthIncompatibilityData;
import com.cburch.logisim.circuit.WireSet;
import com.cburch.logisim.comp.Component;
import com.cburch.logisim.comp.ComponentDrawContext;
import com.cburch.logisim.data.BitWidth;
import com.cburch.logisim.data.Bounds;
import com.cburch.logisim.data.Location;
import com.cburch.logisim.data.Value;
import com.cburch.logisim.gui.generic.GridPainter;
import com.cburch.logisim.prefs.AppPreferences;
import com.cburch.logisim.proj.Project;
import com.cburch.logisim.tools.Tool;
import com.cburch.logisim.util.GraphicsUtil;

class CanvasPainter implements PropertyChangeListener {
    private static final Set<Component> NO_COMPONENTS = Collections.emptySet();

    private Canvas canvas;
    private GridPainter grid;
    private Component haloedComponent = null;
    private Circuit haloedCircuit = null;
    private WireSet highlightedWires = WireSet.EMPTY;

    CanvasPainter(Canvas canvas) {
        this.canvas = canvas;
        this.grid = new GridPainter(canvas);

        AppPreferences.PRINTER_VIEW.addPropertyChangeListener(this);
        AppPreferences.ATTRIBUTE_HALO.addPropertyChangeListener(this);
    }

    //
    // accessor methods
    //
    GridPainter getGridPainter() {
        return grid;
    }

    Component getHaloedComponent() {
        return haloedComponent;
    }

    //
    // mutator methods
    //
    void setHighlightedWires(WireSet value) {
        highlightedWires = value == null ? WireSet.EMPTY : value;
    }

    void setHaloedComponent(Circuit circ, Component comp) {
        if (comp == haloedComponent) {
            return;
        }

        Graphics g = canvas.getGraphics();
        exposeHaloedComponent(g);
        haloedCircuit = circ;
        haloedComponent = comp;
        exposeHaloedComponent(g);
    }

    private void exposeHaloedComponent(Graphics g) {
        Component c = haloedComponent;
        if (c == null) {
            return;
        }

        Bounds bds = c.getBounds(g).expand(7);
        int w = bds.getWidth();
        int h = bds.getHeight();
        double a = Canvas.SQRT_2 * w;
        double b = Canvas.SQRT_2 * h;
        canvas.repaint((int) Math.round(bds.getX() + w/2.0 - a/2.0),
            (int) Math.round(bds.getY() + h/2.0 - b/2.0),
            (int) Math.round(a), (int) Math.round(b));
    }

    @Override
    public void propertyChange(PropertyChangeEvent event) {
        if (AppPreferences.PRINTER_VIEW.isSource(event)
                || AppPreferences.ATTRIBUTE_HALO.isSource(event)) {
            canvas.repaint();
        }
    }


    //
    // painting methods
    //
    void paintContents(Graphics g, Project proj) {
        Rectangle clip = g.getClipBounds();
        Dimension size = canvas.getSize();
        double zoomFactor = canvas.getZoomFactor();
        if (canvas.ifPaintDirtyReset() || clip == null) {
            clip = new Rectangle(0, 0, size.width, size.height);
        }
        g.setColor(Color.white);
        g.fillRect(clip.x, clip.y, clip.width, clip.height);

        grid.paintGrid(g);
        g.setColor(Color.black);

        Graphics gScaled = g.create();
        if (zoomFactor != 1.0 && gScaled instanceof Graphics2D) {
            ((Graphics2D) gScaled).scale(zoomFactor, zoomFactor);
        }
        drawWithUserState(g, gScaled, proj);
        drawWidthIncompatibilityData(g, gScaled, proj);
        Circuit circ = proj.getCurrentCircuit();

        CircuitState circState = proj.getCircuitState();
        ComponentDrawContext ptContext = new ComponentDrawContext(canvas,
                circ, circState, g, gScaled);
        ptContext.setHighlightedWires(highlightedWires);
        gScaled.setColor(Color.RED);
        circState.drawOscillatingPoints(ptContext);
        gScaled.setColor(Color.BLUE);
        proj.getSimulator().drawStepPoints(ptContext);
        gScaled.dispose();
    }

    private void drawWithUserState(Graphics base, Graphics g, Project proj) {
        Circuit circ = proj.getCurrentCircuit();
        Selection sel = proj.getSelection();
        Set<Component> hidden;
        Tool dragTool = canvas.getDragTool();
        if (dragTool == null) {
            hidden = NO_COMPONENTS;
        } else {
            hidden = dragTool.getHiddenComponents(canvas);
            if (hidden == null) {
                hidden = NO_COMPONENTS;
            }

        }

        // draw halo around component whose attributes we are viewing
        boolean showHalo = AppPreferences.ATTRIBUTE_HALO.getBoolean();
        if (showHalo && haloedComponent != null && haloedCircuit == circ
                && !hidden.contains(haloedComponent)) {
            GraphicsUtil.switchToWidth(g, 3);
            g.setColor(Canvas.HALO_COLOR);
            Bounds bds = haloedComponent.getBounds(g).expand(5);
            int w = bds.getWidth();
            int h = bds.getHeight();
            double a = Canvas.SQRT_2 * w;
            double b = Canvas.SQRT_2 * h;
            g.drawOval((int) Math.round(bds.getX() + w/2.0 - a/2.0),
                (int) Math.round(bds.getY() + h/2.0 - b/2.0),
                (int) Math.round(a), (int) Math.round(b));
            GraphicsUtil.switchToWidth(g, 1);
            g.setColor(Color.BLACK);
        }

        // draw circuit and selection
        CircuitState circState = proj.getCircuitState();
        boolean printerView = AppPreferences.PRINTER_VIEW.getBoolean();
        ComponentDrawContext context = new ComponentDrawContext(canvas,
                circ, circState, base, g, printerView);
        context.setHighlightedWires(highlightedWires);
        circ.draw(context, hidden);
        sel.draw(context, hidden);

        // draw tool
        Tool tool = dragTool != null ? dragTool : proj.getTool();
        if (tool != null && !canvas.isPopupMenuUp()) {
            Graphics gCopy = g.create();
            context.setGraphics(gCopy);
            tool.draw(canvas, context);
            gCopy.dispose();
        }
    }

    private void drawWidthIncompatibilityData(Graphics base, Graphics g, Project proj) {
        Set<WidthIncompatibilityData> exceptions;
        exceptions = proj.getCurrentCircuit().getWidthIncompatibilityData();
        if (exceptions == null || exceptions.size() == 0) {
            return;
        }


        g.setColor(Value.WIDTH_ERROR_COLOR);
        GraphicsUtil.switchToWidth(g, 2);
        FontMetrics fm = base.getFontMetrics(g.getFont());
        for (WidthIncompatibilityData ex : exceptions) {
            for (int i = 0; i < ex.size(); i++) {
                Location p = ex.getPoint(i);
                BitWidth w = ex.getBitWidth(i);

                // ensure it hasn't already been drawn
                boolean drawn = false;
                for (int j = 0; j < i; j++) {
                    if (ex.getPoint(j).equals(p)) {
                        { drawn = true;
                    }
break; }
                }
                if (drawn) {
                    continue;
                }


                // compute the caption combining all similar points
                String caption = "" + w.getWidth();
                for (int j = i + 1; j < ex.size(); j++) {
                    if (ex.getPoint(j).equals(p)) {
                        { caption += "/" + ex.getBitWidth(j);
                    }
break; }
                }
                g.drawOval(p.getX() - 4, p.getY() - 4, 8, 8);
                g.drawString(caption, p.getX() + 5, p.getY() + 2 + fm.getAscent());
            }
        }
        g.setColor(Color.BLACK);
        GraphicsUtil.switchToWidth(g, 1);
    }
}
TOP

Related Classes of com.cburch.logisim.gui.main.CanvasPainter

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.