Package org.joshy.sketch.model

Source Code of org.joshy.sketch.model.SShape$SShapeListener

package org.joshy.sketch.model;

import org.joshy.gfx.draw.FlatColor;
import org.joshy.gfx.draw.GFX;
import org.joshy.gfx.draw.ImageBuffer;
import org.joshy.gfx.draw.Paint;
import org.joshy.gfx.draw.effects.BlurEffect;
import org.joshy.gfx.node.Bounds;
import org.joshy.gfx.stage.swing.SwingGFX;

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.util.ArrayList;
import java.util.List;

public abstract class SShape extends SNode {
    public Paint fillPaint = FlatColor.GRAY;
    public FlatColor strokePaint = FlatColor.BLACK;
    private double strokeWidth = 1;
    private double fillOpacity = 1.0;
    private DropShadow shadow = null;
    private List<SShapeListener> listeners = new ArrayList<SShapeListener>();
    private ImageBuffer buf;
    private DropShadow oldShadow;
    private double oldWidth;
    private double oldHeight;
    private boolean oldInner;
    private boolean contentChanged = true;

    public Paint getFillPaint() {
        return fillPaint;
    }

    public SShape setFillPaint(Paint fillPaint) {
        this.fillPaint = fillPaint;
        return this;
    }

    public FlatColor getStrokePaint() {
        return strokePaint;
    }

    public void setStrokePaint(FlatColor strokePaint) {
        this.strokePaint = strokePaint;
        markContentChanged();
    }

    public void setStrokeWidth(double strokeWidth) {
        this.strokeWidth = strokeWidth;
        markContentChanged();
    }

    public double getStrokeWidth() {
        return strokeWidth;
    }

    public SNode duplicate(SNode dupe) {
        if(dupe == null) throw new IllegalArgumentException("SShape.duplicate: duplicate shape argument can't be null!");
        ((SShape)dupe).setFillPaint(this.getFillPaint().duplicate());
        ((SShape)dupe).setFillOpacity(this.getFillOpacity());
        ((SShape)dupe).setStrokePaint(this.getStrokePaint());
        ((SShape)dupe).setStrokeWidth(this.getStrokeWidth());
        return super.duplicate(dupe);
    }

    public double getFillOpacity() {
        return fillOpacity;
    }

    public void setFillOpacity(double fillOpacity) {
        this.fillOpacity = fillOpacity;
        markContentChanged();
    }


    @Override
    public void setTranslateX(double translateX) {
        super.setTranslateX(translateX);
        fireUpdate();
    }

    @Override
    public void setTranslateY(double translateY) {
        super.setTranslateY(translateY);
        fireUpdate();
    }

    public abstract Area toArea();

    protected void drawShadow(GFX g) {
        if(shadow != null) {
            int blurRadius = shadow.getBlurRadius();
            if(blurRadius <= 0) blurRadius = 0;
            double xoff = shadow.getXOffset();
            double yoff = shadow.getYOffset();
            Bounds b = getBounds();

            if(buf == null
                    || shadow != oldShadow
                    || b.getWidth() != oldWidth
                    || b.getHeight() != oldHeight
                    || shadow.isInner() != oldInner
                    || contentChanged) {
                if(shadow.isInner()) {
                    regenInnerShadow(g);
                } else {
                    regenShadow(g);
                }
                oldInner = shadow.isInner();
                contentChanged = false;
            }
            double oldOpacity = g.getOpacity();
            g.setOpacity(shadow.getOpacity());
            g.draw(buf,b.getX()-blurRadius*2+xoff,b.getY()-blurRadius*2+yoff);
            g.setOpacity(oldOpacity);
        }
    }

    protected void initPaint(GFX g) {
        Paint paint = this.getFillPaint();
        if(paint != null) {
            if(paint instanceof FlatColor) {
                g.setPaint(((FlatColor)paint).deriveWithAlpha(getFillOpacity()));
            }
        }
    }

    protected void regenInnerShadow(GFX g) {
        //setup
        int blurRadius = 5;
        Bounds b = getBounds();
        ImageBuffer bufx = g.createBuffer(
                (int)b.getWidth()+blurRadius*2,
                (int)b.getHeight()+blurRadius*2);

        //render shadow to buffer
        bufx.clear();
        GFX g2 = bufx.getGFX();
        g2.setPaint(FlatColor.BLACK);
        g2.translate(10, 10);
        fillShape(g2);
        g2.translate(-10, -10);
        bufx.apply(new BlurEffect(blurRadius));
        g2.dispose();

        //invert alpha channel
        for(int i=0; i<bufx.buf.getWidth(); i++) {
            for(int j=0; j<bufx.buf.getHeight(); j++) {
                int rgb = bufx.buf.getRGB(i,j);
                int a = (0xFF000000 & rgb)>>24;
                a = 255-a;
                rgb = (rgb & 0x00FFFFFF) | (a<<24);
                bufx.buf.setRGB(i,j,rgb);
            }
        }


        //composite using a boolean op to mask out the bg
        buf = g.createBuffer(
                (int)b.getWidth()+blurRadius*2,
                (int)b.getHeight()+blurRadius*2);
        SwingGFX gx =(SwingGFX)buf.getGFX();
        Graphics2D graphics2D = (Graphics2D) gx.getNative();
        graphics2D.setComposite(AlphaComposite.SrcOver);

        initPaint(gx);
        fillShape(gx);
        graphics2D.setComposite(AlphaComposite.SrcAtop);
        gx.draw(bufx, -5, -5);
        gx.dispose();

    }

    public Bounds getEffectBounds() {
        if(getShadow() == null) {
            return getBounds();
        }
        Bounds bounds = getBounds();
        int rad = shadow.getBlurRadius();
        double xoff = shadow.getXOffset();
        double yoff = shadow.getYOffset();
        Bounds shadowBounds = new Bounds(bounds.getX()+xoff-rad,bounds.getY()+yoff-rad,bounds.getWidth()+xoff+rad,bounds.getHeight()+yoff+rad);
        Bounds union = bounds.union(shadowBounds);
        return union;
    }
    protected void regenShadow(GFX g) {
        //setup
        int blurRadius = shadow.getBlurRadius()*2;
        Bounds b = getBounds();
        oldWidth = b.getWidth();
        oldHeight = b.getHeight();
        buf = g.createBuffer(
                (int)b.getWidth()+blurRadius*2,
                (int)b.getHeight()+blurRadius*2);

        //draw shape with shadow color
        GFX g2 = buf.getGFX();

        //fill shape with black
        g2.setPaint(FlatColor.BLACK);
        g2.translate(blurRadius,blurRadius);
        g2.translate(-b.getX(),-b.getY());
        initPaint(g2);
        fillShape(g2);
        drawShape(g2);
        g2.translate(b.getX(),b.getY());
        //blur
        buf.apply(new BlurEffect(blurRadius));
        g2.translate(-blurRadius,-blurRadius);
        //use blur as alpha mask to draw in the real color
        buf.apply(new WipeColorEffect(shadow.getColor()));

        oldShadow = shadow;
    }

    protected void drawShape(GFX g) { }

    protected void fillShape(GFX g) { }

    public SShape setShadow(DropShadow shadow) {
        this.shadow = shadow;
        return this;
    }

    public DropShadow getShadow() {
        return this.shadow;
    }

    public void addListener(SShapeListener gradientHandle) {
        listeners.add(gradientHandle);
    }

    protected void markContentChanged() {
        contentChanged = true;
    }

    protected void fireUpdate() {
        if(listeners != null) {
            for(SShapeListener c : listeners) {
                c.changed();
            }
        }
    }

    public void removeListener(SShapeListener gradientHandle) {
        listeners.remove(gradientHandle);
    }

    public SPath toPath() {
        return null;
    }

    protected Shape transformShape(Shape sh) {
        AffineTransform af = new AffineTransform();
        af.translate(getTranslateX(),getTranslateY());
        af.translate(getAnchorX(),getAnchorY());
        af.rotate(Math.toRadians(getRotate()));
        af.scale(getScaleX(), getScaleY());
        af.translate(-getAnchorX(),-getAnchorY());
        return af.createTransformedShape(sh);
    }

    public static interface SShapeListener {
        public void changed();
    }
}
TOP

Related Classes of org.joshy.sketch.model.SShape$SShapeListener

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.