allow disable label with mathml or latex values 83/14183/2
Antoine ELIAS [Thu, 27 Mar 2014 17:51:49 +0000 (18:51 +0100)]
Change-Id: Ibaa6ba617c5159175cf1a029a0725997bd2b2a61

scilab/modules/gui/src/java/org/scilab/modules/gui/bridge/label/SwingScilabLabel.java

index da84c40..f065f8c 100644 (file)
@@ -18,13 +18,22 @@ import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProp
 import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
 
 import javax.imageio.ImageIO;
 import javax.swing.BorderFactory;
+import javax.swing.GrayFilter;
+import javax.swing.Icon;
 import javax.swing.ImageIcon;
 import javax.swing.JComponent;
 import javax.swing.JEditorPane;
@@ -40,11 +49,15 @@ import javax.swing.event.HyperlinkListener;
 import javax.swing.text.html.HTMLDocument;
 import javax.swing.text.html.StyleSheet;
 
+import org.scilab.forge.jlatexmath.TeXConstants;
+import org.scilab.forge.jlatexmath.TeXFormula;
+import org.scilab.forge.jlatexmath.TeXIcon;
 import org.scilab.modules.commons.gui.FindIconHelper;
 import org.scilab.modules.console.utils.ScilabSpecialTextUtilities;
 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
 import org.scilab.modules.gui.SwingViewObject;
 import org.scilab.modules.gui.SwingViewWidget;
+import org.scilab.modules.gui.bridge.label.SwingScilabLabel.IconLabel.IconType;
 import org.scilab.modules.gui.events.callback.CommonCallBack;
 import org.scilab.modules.gui.label.SimpleLabel;
 import org.scilab.modules.gui.menubar.MenuBar;
@@ -65,6 +78,10 @@ import org.scilab.modules.gui.utils.WebBrowser;
  */
 public class SwingScilabLabel extends JScrollPane implements SwingViewObject, SimpleLabel {
 
+    private enum LabelStyle {
+        TEXT, LATEX, MATHML, HTML
+    };
+
     private static final long serialVersionUID = 7177323379068859441L;
 
     private Integer uid;
@@ -73,17 +90,17 @@ public class SwingScilabLabel extends JScrollPane implements SwingViewObject, Si
 
     private Border defaultBorder = null;
 
-    private boolean isJLabel = true;
+    private LabelStyle labelStyle = null;
 
-    private String horizontalAlignment = "left"; /* Horizontal alignment property */
+    private String horizontalAlignment = "left"; //Horizontal alignment property
 
-    private String verticalAlignment = "middle"; /* Vertical alignment property */
+    private String verticalAlignment = "middle"; // Vertical alignment property
 
-    private final JPanel alignmentPanel = new JPanel(); /* Used for alignment */
+    private final JPanel alignmentPanel = new JPanel(); // Used for alignment
 
     private final GridBagLayout alignmentLayout = new GridBagLayout();
 
-    private String labelText = ""; /* Used to save user given text */
+    private String labelText = ""; // Used to save user given text
 
     private static HyperlinkListener urlOpener = new HyperlinkListener() {
         public void hyperlinkUpdate(HyperlinkEvent event) {
@@ -99,8 +116,6 @@ public class SwingScilabLabel extends JScrollPane implements SwingViewObject, Si
     public SwingScilabLabel() {
         super();
         alignmentPanel.setLayout(alignmentLayout);
-        //alignmentPanel.add(label);
-        //getViewport().add(label);
         setViewportView(label);
         setBorder(BorderFactory.createEmptyBorder());
         setViewportBorder(BorderFactory.createEmptyBorder());
@@ -117,7 +132,7 @@ public class SwingScilabLabel extends JScrollPane implements SwingViewObject, Si
         super.setFont(font);
         if (label != null) {
             label.setFont(font);
-            if (!isJLabel) {
+            if (labelStyle == LabelStyle.HTML) {
                 StyleSheet styleSheet = ((HTMLDocument) ((JTextPane) label).getDocument()).getStyleSheet();
                 styleSheet.addRule("body {font-family:" + font.getName() + ";}");
                 styleSheet.addRule("body {font-size:" + font.getSize() + "pt;}");
@@ -164,7 +179,7 @@ public class SwingScilabLabel extends JScrollPane implements SwingViewObject, Si
         }
         if (label != null) {
             if (label instanceof JLabel) {
-                ((JLabel)label).setOpaque(true);
+                ((JLabel) label).setOpaque(true);
             }
             label.setBackground(color);
         }
@@ -206,9 +221,7 @@ public class SwingScilabLabel extends JScrollPane implements SwingViewObject, Si
     public void setDims(Size newSize) {
         setSize(newSize.getWidth(), newSize.getHeight());
         // Need validate to force alignement to be applyed
-        setMinimumSize(new Dimension(
-                           Math.max((int)label.getMinimumSize().getWidth(), newSize.getWidth()),
-                           (int)label.getMinimumSize().getHeight()));
+        setMinimumSize(new Dimension(Math.max((int) label.getMinimumSize().getWidth(), newSize.getWidth()), (int) label.getMinimumSize().getHeight()));
     }
 
     /**
@@ -338,52 +351,53 @@ public class SwingScilabLabel extends JScrollPane implements SwingViewObject, Si
     public void setText(String newText) {
         // Save the data given by the user so that it can be retrieved
         // (Java adds HTML tags in the getlabel().getText() returned value)
+
+        // <math></math>    : LateXLabel ( MathML )
+        // <html></html>    : JTextPane for clickable links
+        // $...$            : LateXLabel ( LateX )
+        // else             : JLabel
+
         labelText = newText;
-        if (labelText.startsWith("<")) {
-            // Try if we are in MathML
-            if (isJLabel && ScilabSpecialTextUtilities.setText(label, newText)) {
-                // MathML in JLabel : OK
-                // Rendering will be done using Icon
-                ((JLabel) label).setText(null);
-            } else if (!isJLabel) {
-                // Try rendering in a new JLabel
-                if (ScilabSpecialTextUtilities.setText(new JLabel(), newText)) {
-                    // MathML in JEditorPane : Change component
-                    changeLabelType(!isJLabel);
-                    ScilabSpecialTextUtilities.setText(label, newText);
-                    // Rendering will be done using Icon
-                    ((JLabel) label).setText(null);
-                } else {
-                    // HTML in JEditorPane : OK
-                    ((JEditorPane) label).setText(newText);
-                }
+        if (labelText.startsWith("<math>") && labelText.endsWith("</math>")) {
+            boolean mathML = ScilabSpecialTextUtilities.setText(new JLabel(), labelText);
+
+            //if MAthML rendering failed use normal renderer ( JLabel)
+            if (mathML) {
+                changeLabelType(LabelStyle.MATHML);
+                ((IconLabel) label).setText(labelText);
             } else {
-                // HTML in JLabel :
-                changeLabelType(!isJLabel);
-                ((JEditorPane) label).setText(newText);
-            }
-        } else {
-            if (!isJLabel) {
-                changeLabelType(!isJLabel);
+                changeLabelType(LabelStyle.TEXT);
+                ((JLabel) label).setText(labelText);
             }
+            return;
+        }
 
-            if (!ScilabSpecialTextUtilities.setText(label, newText)) {
-                // Normal Text
-                if (!newText.isEmpty()) {
-                    ((JLabel) label).setText(newText);
-                } else {
-                    ((JLabel) label).setText(" ");
-                }
+        if (labelText.startsWith("<html>") && labelText.endsWith("</html>")) {
+            changeLabelType(LabelStyle.HTML);
+            ((JEditorPane) label).setText(labelText);
+            return;
+        }
+
+        if (labelText.startsWith("$") && labelText.endsWith("$")) {
+            boolean latex = ScilabSpecialTextUtilities.setText(new JLabel(), labelText);
+
+            //if MAthML rendering failed use normal renderer ( JLabel)
+            if (latex) {
+                changeLabelType(LabelStyle.LATEX);
+                ((IconLabel) label).setText(labelText);
             } else {
-                // Latex or MathML : Rendering will be done using Icon
-                ((JLabel) label).setText(null);
+                changeLabelType(LabelStyle.TEXT);
+                ((JLabel) label).setText(labelText);
             }
-
-            ((JLabel) label).invalidate();
-            ((JLabel) label).validate();
-            ((JLabel) label).repaint();
+            return;
         }
 
+        changeLabelType(LabelStyle.TEXT);
+        ((JLabel) label).setText(labelText);
+
+        ((JLabel) label).invalidate();
+        ((JLabel) label).validate();
+        ((JLabel) label).repaint();
     }
 
     /**
@@ -391,44 +405,63 @@ public class SwingScilabLabel extends JScrollPane implements SwingViewObject, Si
      * quicker on simple text JEditorPane can enable HyperLinks
      * @param isHtmlLabel
      */
-    private void changeLabelType(boolean isJLabel) {
-        this.isJLabel = isJLabel;
+    private void changeLabelType(LabelStyle style) {
+
+        if (labelStyle == style) {
+            return;
+        }
+
+        labelStyle = style;
         Color bgColor = label.getBackground();
         Color fgColor = label.getForeground();
         Font font = label.getFont();
         Dimension dims = label.getSize();
         label.setVisible(false);
 
-        if (!isJLabel) {
-            JTextPane newLabel = new JTextPane();
-            newLabel.addHyperlinkListener(urlOpener);
-            newLabel.setContentType("text/html");
-            newLabel.setEditable(false);
-            StyleSheet styleSheet = ((HTMLDocument) newLabel.getDocument()).getStyleSheet();
-            styleSheet.addRule("body {font-family:" + font.getName() + ";}");
-            styleSheet.addRule("body {font-size:" + font.getSize() + "pt;}");
-            if (font.isBold()) {
-                styleSheet.addRule("body {font-weight:bold;}");
-            } else {
-                styleSheet.addRule("body {font-weight:normal;}");
+        switch (labelStyle) {
+            case LATEX:
+                alignmentPanel.remove(label);
+                label = new IconLabel(IconType.LATEX);
+                setViewportView(label);
+                break;
+            case MATHML:
+                alignmentPanel.remove(label);
+                label = new IconLabel(IconType.MATHML);
+                setViewportView(label);
+                break;
+            case HTML: {
+                JTextPane newLabel = new JTextPane();
+                newLabel.addHyperlinkListener(urlOpener);
+                newLabel.setContentType("text/html");
+                newLabel.setEditable(false);
+                StyleSheet styleSheet = ((HTMLDocument) newLabel.getDocument()).getStyleSheet();
+                styleSheet.addRule("body {font-family:" + font.getName() + ";}");
+                styleSheet.addRule("body {font-size:" + font.getSize() + "pt;}");
+                if (font.isBold()) {
+                    styleSheet.addRule("body {font-weight:bold;}");
+                } else {
+                    styleSheet.addRule("body {font-weight:normal;}");
+                }
+                if (font.isItalic()) {
+                    styleSheet.addRule("body {font-style:italic;}");
+                } else {
+                    styleSheet.addRule("body {font-style:normal;}");
+                }
+
+                label = newLabel;
+                alignmentPanel.add(label);
+                setViewportView(alignmentPanel);
+                break;
             }
-            if (font.isItalic()) {
-                styleSheet.addRule("body {font-style:italic;}");
-            } else {
-                styleSheet.addRule("body {font-style:normal;}");
+            case TEXT: {
+                alignmentPanel.remove(label);
+                label = new JLabel();
+                setViewportView(label);
+                //refresh icon
+                update(__GO_UI_ICON__, GraphicController.getController().getProperty(getId(), __GO_UI_ICON__));
+                ((JLabel) label).setOpaque(false);
+                break;
             }
-
-            label = newLabel;
-            alignmentPanel.add(label);
-            setViewportView(alignmentPanel);
-        } else {
-            alignmentPanel.remove(label);
-            label = new JLabel();
-            setViewportView(label);
-            //refresh icon
-            update(__GO_UI_ICON__, GraphicController.getController().getProperty(getId(), __GO_UI_ICON__));
-            setAlignment();
-            ((JLabel)label).setOpaque(false);
         }
 
         setBackground(bgColor);
@@ -436,6 +469,7 @@ public class SwingScilabLabel extends JScrollPane implements SwingViewObject, Si
         label.setFont(font);
         label.setSize(dims);
         label.setVisible(true);
+        setAlignment();
     }
 
     /**
@@ -443,11 +477,12 @@ public class SwingScilabLabel extends JScrollPane implements SwingViewObject, Si
      */
     private void setAlignment() {
 
-        if (isJLabel) {
-            ((JLabel)label).setVerticalAlignment(ScilabAlignment.toSwingAlignment(verticalAlignment));
-            ((JLabel)label).setHorizontalAlignment(ScilabAlignment.toSwingAlignment(horizontalAlignment));
+        if (labelStyle != LabelStyle.HTML) {
+            ((JLabel) label).setVerticalAlignment(ScilabAlignment.toSwingAlignment(verticalAlignment));
+            ((JLabel) label).setHorizontalAlignment(ScilabAlignment.toSwingAlignment(horizontalAlignment));
             return;
         }
+
         GridBagConstraints gbc = new GridBagConstraints();
 
         gbc.gridx = 0;
@@ -526,7 +561,7 @@ public class SwingScilabLabel extends JScrollPane implements SwingViewObject, Si
     public void update(int property, Object value) {
         switch (property) {
             case __GO_UI_ICON__: {
-                if (isJLabel) {
+                if (labelStyle == LabelStyle.TEXT) {
                     String icon = (String) value;
                     if (icon != null && icon.equals("") == false) {
                         File file = new File((String) value);
@@ -542,8 +577,6 @@ public class SwingScilabLabel extends JScrollPane implements SwingViewObject, Si
                     } else {
                         ((JLabel) label).setIcon(null);
                     }
-                } else {
-                    //Icon in JEditorPane ?
                 }
                 break;
             }
@@ -558,16 +591,165 @@ public class SwingScilabLabel extends JScrollPane implements SwingViewObject, Si
         if (color != null) {
             //bypass setBackground
             if (label instanceof JLabel) {
-                ((JLabel)label).setOpaque(true);
+                ((JLabel) label).setOpaque(true);
             }
             label.setBackground(color);
         }
     }
 
     public void resetForeground() {
-        Color color = (Color)UIManager.getLookAndFeelDefaults().get("Label.foreground");
+        Color color = (Color) UIManager.getLookAndFeelDefaults().get("Label.foreground");
         if (color != null) {
             label.setForeground(color);
         }
     }
+
+    /**
+     * Component to display LaTeX Thank you Calixte
+     */
+    public static class IconLabel extends JLabel {
+        public enum IconType {
+            LATEX, MATHML
+        };
+
+        private static final long serialVersionUID = 3885565301114930030L;
+        private final static Font DEFAULTFONT = new Font("serif", Font.PLAIN, 12);
+        private final static boolean isWindows = System.getProperty("os.name").toLowerCase().indexOf("win") != -1;
+
+        private Icon icon;
+        private Icon iconDisable;
+        private float fontSize;
+        private String text;
+        private Dimension preferred;
+        IconType type = IconType.MATHML;
+
+        public IconLabel(IconType type) {
+            super();
+            fontSize = 12f;
+            icon = null;
+            iconDisable = null;
+            preferred = new Dimension(0, 0);
+            this.type = type;
+        }
+
+        /**
+         * Set the LaTeX content
+         * @param text the LaTeX
+         */
+        public void setText(String text) {
+            this.text = text;
+            update();
+        }
+
+        /**
+         * Get the LaTeX content
+         * @return the LaTeX string
+         */
+        public String getText() {
+            return text;
+        }
+
+        public Dimension getPreferredSize() {
+            return preferred;
+        }
+
+        public Dimension getMinimumSize() {
+            return getPreferredSize();
+        }
+
+        protected void paintComponent(Graphics g) {
+            super.paintComponent(g);
+            if (isOpaque() && getBackground() != null) {
+                final Color old = g.getColor();
+                g.setColor(getBackground());
+                g.fillRect(0, 0, getWidth(), getHeight());
+                g.setColor(old);
+            }
+
+            int h = getHorizontalAlignment();
+            int v = getVerticalAlignment();
+
+            int x = 0;
+            int y = 0;
+
+            if (h == JLabel.CENTER) {
+                x = (getSize().width - icon.getIconWidth()) / 2;
+            } else if (h == JLabel.RIGHT) {
+                x = getSize().width - icon.getIconWidth();
+            }
+
+            if (v == JLabel.CENTER) {
+                y = (getSize().height - icon.getIconHeight()) / 2;
+            } else if (v == JLabel.BOTTOM) {
+                y = getSize().height - icon.getIconHeight();
+            }
+
+            if (type == IconType.LATEX) {
+                TeXIcon latex = (TeXIcon) icon;
+                if (isEnabled()) {
+                    latex.setForeground(getForeground());
+                    latex.paintIcon(this, g, x, y);
+                } else {
+                    if (isWindows && (UIManager.getColor("Label.disabledForeground") instanceof Color) && (UIManager.getColor("Label.disabledShadow") instanceof Color)) {
+                        latex.setForeground(UIManager.getColor("Label.disabledShadow"));
+                        latex.paintIcon(this, g, x + 1, y + 1);
+                        latex.setForeground(UIManager.getColor("Label.disabledForeground"));
+                        latex.paintIcon(this, g, x, y);
+                    } else {
+                        latex.setForeground(getBackground().brighter());
+                        latex.paintIcon(this, g, x + 1, y + 1);
+                        latex.setForeground(getBackground().darker());
+                        latex.paintIcon(this, g, x, y);
+                    }
+                }
+            } else { //MathML
+                //enable/disable is made @ icon generation in ScilabSpecialTextUtilities
+                if (isEnabled()) {
+                    icon.paintIcon(this, g, x, y);
+                } else {
+                    icon.paintIcon(this, g, x + 1, y + 1);
+                    iconDisable.paintIcon(this, g, x, y);
+                }
+            }
+        }
+
+        public void setFont(Font f) {
+            this.fontSize = f.getSize2D();
+            update();
+        }
+
+        public Font getFont() {
+            return DEFAULTFONT;
+        }
+
+        /**
+         * Update the component
+         */
+        private void update() {
+            if (text.equals("") == false) {
+                if (type == IconType.LATEX) {
+                    icon = ScilabSpecialTextUtilities.compileLaTeXExpression(text, (int) fontSize);
+                } else {
+                    if (isEnabled()) {
+                        icon = ScilabSpecialTextUtilities.compileMathMLExpression(text, (int) fontSize);
+                    } else {
+                        if (isWindows && (UIManager.getColor("Label.disabledForeground") instanceof Color) && (UIManager.getColor("Label.disabledShadow") instanceof Color)) {
+                            icon = ScilabSpecialTextUtilities.compileMathMLExpression(text, (int) fontSize, UIManager.getColor("Label.disabledShadow"));
+                            iconDisable = ScilabSpecialTextUtilities.compileMathMLExpression(text, (int) fontSize, UIManager.getColor("Label.disabledForeground"));
+                        } else {
+                            icon = ScilabSpecialTextUtilities.compileMathMLExpression(text, (int) fontSize, getBackground().brighter());
+                            iconDisable = ScilabSpecialTextUtilities.compileMathMLExpression(text, (int) fontSize, getBackground().darker());
+                        }
+                    }
+                }
+                preferred = new Dimension(icon.getIconWidth(), icon.getIconHeight());
+                revalidate();
+            }
+        }
+
+        public void setEnabled(boolean enabled) {
+            super.setEnabled(enabled);
+            update();
+        }
+    }
 }