001    /*
002     * Copyright 2007 - 2009 JEuclid, http://jeuclid.sf.net
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    /* $Id: MathView.java,v 2986a8eeaebc 2009/09/24 12:53:08 max $ */
018    
019    package net.sourceforge.jeuclid.swt;
020    
021    import net.sourceforge.jeuclid.MutableLayoutContext;
022    import net.sourceforge.jeuclid.context.LayoutContextImpl;
023    import net.sourceforge.jeuclid.elements.generic.DocumentElement;
024    
025    import org.eclipse.swt.events.DisposeEvent;
026    import org.eclipse.swt.events.DisposeListener;
027    import org.eclipse.swt.events.PaintEvent;
028    import org.eclipse.swt.events.PaintListener;
029    import org.eclipse.swt.graphics.Color;
030    import org.eclipse.swt.graphics.Device;
031    import org.eclipse.swt.graphics.GC;
032    import org.eclipse.swt.graphics.Image;
033    import org.eclipse.swt.graphics.ImageData;
034    import org.eclipse.swt.widgets.Canvas;
035    import org.eclipse.swt.widgets.Composite;
036    import org.w3c.dom.Node;
037    
038    /**
039     * Contains a display component for SWT.
040     * <p>
041     * TODO: This is a very basic implementation.
042     * 
043     * @version $Revision: 2986a8eeaebc $
044     */
045    public final class MathView extends Canvas {
046    
047        // /**
048        // * Logger for this class
049        // */
050        // private static final Log LOGGER = LogFactory.getLog(MathView.class);
051    
052        private final MathRenderer mathRenderer = MathRenderer.getInstance();
053    
054        private Node document;
055    
056        private ImageData renderedFormula;
057    
058        private MutableLayoutContext layoutContext = new LayoutContextImpl(
059                LayoutContextImpl.getDefaultLayoutContext());
060    
061        /**
062         * Create a new MathView Widget.
063         * 
064         * @param parent
065         *            Parent component
066         * @param style
067         *            SWT style attributes.
068         */
069        public MathView(final Composite parent, final int style) {
070            super(parent, style);
071            this.setDocument(new DocumentElement());
072            this.addDisposeListener(new DisposeListener() {
073                public void widgetDisposed(final DisposeEvent e) {
074                    MathView.this.widgetDisposed(e);
075                }
076            });
077            this.addPaintListener(new PaintListener() {
078                public void paintControl(final PaintEvent e) {
079                    MathView.this.paintControl(e);
080                }
081            });
082        }
083    
084        private void paintControl(final PaintEvent e) {
085            final GC gc = e.gc;
086            final Device device = gc.getDevice();
087            final Color c = new Color(device, 255, 255, 255);
088            gc.setBackground(c);
089            gc.fillRectangle(e.x, e.y, e.width, e.height);
090            c.dispose();
091            if (this.renderedFormula != null) {
092                final Image im = new Image(device, this.renderedFormula);
093                gc.drawImage(im, 0, 0);
094                im.dispose();
095            }
096        }
097    
098        private void widgetDisposed(final DisposeEvent e) {
099            this.document = null;
100            this.renderedFormula = null;
101        }
102    
103        private void recreate() {
104            this.renderedFormula = this.mathRenderer.render(this.document,
105                    this.layoutContext);
106        }
107    
108        /**
109         * @param doc
110         *            the document to set
111         */
112        public void setDocument(final Node doc) {
113            final Node oldValue = this.document;
114            this.document = doc;
115            if (doc != oldValue) {
116                this.recreate();
117                this.redraw();
118            }
119        }
120    
121        /**
122         * @return the document
123         */
124        public Node getDocument() {
125            return this.document;
126        }
127    
128    }