Package org.itsnat.feashow.features.core.otherns

Source Code of org.itsnat.feashow.features.core.otherns.SVGInHTMLMimeSVGWebDocument

/*
* This file is not part of the ItsNat framework.
*
* Original source code use and closed source derivatives are authorized
* to third parties with no restriction or fee.
* The original source code is owned by the author.
*
* This program is distributed AS IS 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.
*
* (C) Innowhere Software a service of Jose Maria Arranz Santamaria, Spanish citizen.
*/

package org.itsnat.feashow.features.core.otherns;


import java.io.Serializable;
import java.util.Date;
import org.itsnat.core.ItsNatDocument;
import org.itsnat.core.domutil.ElementGroupManager;
import org.itsnat.core.domutil.ElementList;
import org.itsnat.core.event.NodePropertyTransport;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.html.HTMLDocument;
import org.w3c.dom.html.HTMLInputElement;
import org.w3c.dom.views.AbstractView;
import org.w3c.dom.views.DocumentView;

public class SVGInHTMLMimeSVGWebDocument implements EventListener,Serializable
{
    protected ItsNatDocument itsNatDoc;
    protected Element svgElem;
    protected Element circleListElem;
    protected ElementList circleList;
    protected Element selectedCircle;
    protected Element textElem;
    protected Element addCircleElem;
    protected Element removeCircleElem;
    protected Element biggerCircleElem;
    protected Element smallerCircleElem;
    protected Element reinsertElem;
    protected HTMLInputElement useSVGLoadElem;

    public SVGInHTMLMimeSVGWebDocument(ItsNatDocument itsNatDoc)
    {
        this.itsNatDoc = itsNatDoc;
        load();
    }

    public void load()
    {
        Document doc = itsNatDoc.getDocument();

        // When the document is loading we cannot access the SVGWeb DOM nodes
        // in client with JavaScript (there is still no SVG DOM),
        // we must wait to the load event.
        // If fastLoad mode is true we can change the SVGWeb DOM in server because no JavaScript
        // code is generated, this is not valid to the attachment of event listeners
        // (JavaScript code is generated and SVG DOM nodes are needed in client).
        // Anyway the best practice is to delegate to the load event.
        // This is not needed of course with native (non-Flash) SVG.

        EventListener listener = new EventListenerSerial() // EventListenerSerial instead of EventListener because this example runs on GAE
        {
            public void handleEvent(Event evt)
            {
                loadSVG();
            }
        };
        AbstractView view = ((DocumentView)doc).getDefaultView();
        ((EventTarget)view).addEventListener("SVGLoad",listener,false);

        this.addCircleElem = doc.getElementById("addCircleId");
        ((EventTarget)addCircleElem).addEventListener("click",this,false);

        this.removeCircleElem = doc.getElementById("removeCircleId");
        ((EventTarget)removeCircleElem).addEventListener("click",this,false);

        this.biggerCircleElem = doc.getElementById("biggerCircleId");
        ((EventTarget)biggerCircleElem).addEventListener("click",this,false);

        this.smallerCircleElem = doc.getElementById("smallerCircleId");
        ((EventTarget)smallerCircleElem).addEventListener("click",this,false);

        this.reinsertElem = doc.getElementById("reinsertId");
        ((EventTarget)reinsertElem).addEventListener("click",this,false);

        this.useSVGLoadElem = (HTMLInputElement)doc.getElementById("useSVGLoadId");
        itsNatDoc.addEventListener((EventTarget)useSVGLoadElem,"click",this,false,new NodePropertyTransport("checked",boolean.class));
    }

    public void loadSVG()
    {
        Document doc = itsNatDoc.getDocument();

        this.svgElem = doc.getElementById("svgId");

        this.circleListElem = doc.getElementById("circleListId");
        ElementGroupManager egm = itsNatDoc.getElementGroupManager();
        this.circleList = egm.createElementList(circleListElem,true);
        circleList.addElement();
        itsNatDoc.addEventListener(((EventTarget)circleListElem),"click",this,false);

        this.textElem = doc.getElementById("textId");
        ((Text)textElem.getFirstChild()).setData(new Date().toString());
    }

    public void handleEvent(Event evt)
    {
        EventTarget currTarget = evt.getCurrentTarget();
        if (currTarget == circleListElem)
        {
            EventTarget target = evt.getTarget();
            if ((target instanceof Element) &&
                ((Element)target).getLocalName().equals("circle"))
            {
                selectCircle((Element)target);
            }
        }
        else if (currTarget == addCircleElem)
        {
            Element lastElem = circleList.getLastElement();
            if (lastElem == null)
            {
                circleList.addElement(); // Will be based on the pattern
            }
            else
            {
                Element newCircle = circleList.addElement();
                int cx = Integer.parseInt(lastElem.getAttribute("cx"));
                cx += 100;
                newCircle.setAttribute("cx",Integer.toString(cx));
            }
        }
        else if (currTarget == removeCircleElem)
        {
            if (!circleList.isEmpty())
            {
                Element circle = circleList.removeElementAt(circleList.getLength() - 1);
                if (selectedCircle == circle) this.selectedCircle = null;
            }
        }
        else if ((currTarget == biggerCircleElem)||
                 (currTarget == smallerCircleElem))
        {
            if (selectedCircle != null)
            {
                boolean bigger = (currTarget == biggerCircleElem);
                int r = Integer.parseInt(selectedCircle.getAttribute("r"));
                if (bigger) r += 20;
                else { r -= 20; if (r < 0) r = 10; }
                selectedCircle.setAttribute("r",Integer.toString(r));
            }
            else
            {
                itsNatDoc.addCodeToSend("alert('Select a circle');");
            }
        }
        else if (currTarget == reinsertElem)
        {
            selectCircle(null);

            HTMLDocument doc = (HTMLDocument)itsNatDoc.getDocument();
            Element newSVGElem = (Element)svgElem.cloneNode(true);
            Node parent = doc.getBody();
            Node sibling = svgElem.getNextSibling();
            parent.removeChild(svgElem);
            parent.insertBefore(newSVGElem,sibling);
            // Note: In this case we remove FIRST the already inserted
            // SVG node because in this example the new SVG node and the current
            // SVG node in document have the same id attribute and SVGWeb FAILS when two or more
            // <svg> elements into the client document have the same id attrib.
            // Changing temporally the id is not a good idea, SVGWeb is not
            // tolerant to an id change before the SVG is rendered (be careful with ids in SVGWeb nodes
            // SVGWeb internally uses your id for identification purposes).

            this.svgElem = newSVGElem;

            // In theory when new SVG nodes are dynamically inserted to be rendered by SVGWeb,
            // in client these nodes are provisional and will be replaced,
            // after insertion into the document any change to this provisional
            // DOM is not valid, changing attributes of the <svg> element is almost
            // the only action valid, so we cannot change the SVG DOM or add event listeners
            // after insertion. The SVGWeb root node automatically fires a SVGLoad event
            // when rendering is done, this is the moment to change the SVG DOM as is suggested
            // by SVGWeb.

            // In ItsNat a SVGLoad listener is not necessary, that is, you CAN modify
            // and/or add listeners to the SVG DOM immediatelly after insertion,
            // ItsNat automatically queues any JavaScript generated code to be
            // executed when rendering is done.

            // Anyway you also can the SVGLoad approach in server as promoted by SVGWeb.
            // In non-Flash mode (non-MSIE browsers) SVGLoad event is simulated by ItsNat,
            // this avoids us to detect if SVG nodes are Flash or native, the same server code
            // is valid in both cases.
            // In this example both approaches are used.
            // Finally remote view/control WORKS with SVGWeb and dynamic insertion/removing.

            // IMPORTANT: do not mix both approaches, that is do NOT modify SVG DOM
            // immediately after insertion AND attach a SVGLoad listener.

            if (useSVGLoadElem.getChecked())
            {
                EventListener listener = new EventListenerSerial() // EventListenerSerial instead of EventListener because this example runs on GAE
                {
                    public void handleEvent(Event evt)
                    {
                        loadSVG();
                    }
                };
                ((EventTarget)svgElem).addEventListener("SVGLoad",listener,false);

                return; // To avoid the next textElem's setData call
            }
            else
            {
                loadSVG();
            }

        }

        ((Text)textElem.getFirstChild()).setData(new Date().toString());
    }

    public void selectCircle(Element circleElem)
    {
        if (selectedCircle != null)
            selectedCircle.setAttribute("fill","#FF0000");

        if (circleElem != null)
            circleElem.setAttribute("fill","#00FF00");
        this.selectedCircle = circleElem;
    }

    public boolean clickedCircle(int x,int y,Element circle)
    {
        int xc = Integer.parseInt(circle.getAttribute("cx"));
        int yc = Integer.parseInt(circle.getAttribute("cy"));
        int r = Integer.parseInt(circle.getAttribute("r"));
        return (xc - r <= x)&&(x <= xc + r)&&(yc - r <= y)&&(y <= yc + r);
    }
}
TOP

Related Classes of org.itsnat.feashow.features.core.otherns.SVGInHTMLMimeSVGWebDocument

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.