This is an automated email from the git hooks/post-receive script.

ben pushed a commit to branch master
in repository autocomplete.

commit 1f665e5c2d4dc68407d5b8944690170876b9c803
Author: bobbylight <[email protected]>
Date:   Sun Jan 20 07:30:01 2013 +0000

    Adding support for using fancy smancy Substance renderers if a Substance 
Look and Feel is installed.  We don't want a compile time dependency so 
everything is done by reflection and delegation.  This means we don't get 
Substance's rollover effects, but that's a minor issue.
---
 .../ui/autocomplete/AutoCompletePopupWindow.java   |   49 +++++-
 .../ui/autocomplete/CompletionCellRenderer.java    |  161 ++++++++++++++++++--
 src/org/fife/ui/autocomplete/TipUtil.java          |    8 +
 src/org/fife/ui/autocomplete/Util.java             |   83 ++++++++++
 4 files changed, 285 insertions(+), 16 deletions(-)

diff --git a/src/org/fife/ui/autocomplete/AutoCompletePopupWindow.java 
b/src/org/fife/ui/autocomplete/AutoCompletePopupWindow.java
index 4d22903..0956704 100644
--- a/src/org/fife/ui/autocomplete/AutoCompletePopupWindow.java
+++ b/src/org/fife/ui/autocomplete/AutoCompletePopupWindow.java
@@ -123,6 +123,12 @@ class AutoCompletePopupWindow extends JWindow implements 
CaretListener,
         */
        private static final int VERTICAL_SPACE                 = 1;
 
+       /**
+        * The class name of the Substance List UI.
+        */
+       private static final String SUBSTANCE_LIST_UI =
+                       
"org.pushingpixels.substance.internal.ui.SubstanceListUI";
+
 
        /**
         * Constructor.
@@ -130,19 +136,14 @@ class AutoCompletePopupWindow extends JWindow implements 
CaretListener,
         * @param parent The parent window (hosting the text component).
         * @param ac The auto-completion instance.
         */
-       public AutoCompletePopupWindow(Window parent, AutoCompletion ac) {
+       public AutoCompletePopupWindow(Window parent, final AutoCompletion ac) {
 
                super(parent);
                ComponentOrientation o = ac.getTextComponentOrientation();
 
                this.ac = ac;
                model = new CompletionListModel();
-               list = new JList(model) {
-                       public void setUI(ListUI ui) {
-                               // Keep our special UI, no matter what
-                               super.setUI(new FastListUI());
-                       }
-               };
+               list = new PopupList(model);
 
                list.setCellRenderer(new DelegatingCellRenderer());
                list.addListSelectionListener(this);
@@ -920,6 +921,40 @@ class AutoCompletePopupWindow extends JWindow implements 
CaretListener,
        }
 
 
+       /**
+        * The actual list of completion choices in this popup window.
+        */
+       private class PopupList extends JList {
+
+               public PopupList(CompletionListModel model) {
+                       super(model);
+               }
+
+               public void setUI(ListUI ui) {
+                       if (Util.getUseSubstanceRenderers() &&
+                                       
SUBSTANCE_LIST_UI.equals(ui.getClass().getName())) {
+                               // Substance requires its special ListUI be 
installed for
+                               // its renderers to actually render (!), but 
long completion
+                               // lists (e.g. PHPCompletionProvider in 
RSTALanguageSupport)
+                               // will simply populate too slowly on initial 
display (when
+                               // calculating preferred size of all items), so 
in this case
+                               // we give a prototype cell value.
+                               CompletionProvider p = 
ac.getCompletionProvider();
+                               BasicCompletion bc = new BasicCompletion(p, 
"Hello world");
+                               setPrototypeCellValue(bc);
+                       }
+                       else {
+                               // Our custom UI that is faster for long HTML 
completion
+                               // lists.
+                               ui = new FastListUI();
+                               setPrototypeCellValue(null);
+                       }
+                       super.setUI(ui);
+               }
+
+       }
+
+
        class RightAction extends AbstractAction {
 
                public void actionPerformed(ActionEvent e) {
diff --git a/src/org/fife/ui/autocomplete/CompletionCellRenderer.java 
b/src/org/fife/ui/autocomplete/CompletionCellRenderer.java
index 5a82a25..af6365a 100644
--- a/src/org/fife/ui/autocomplete/CompletionCellRenderer.java
+++ b/src/org/fife/ui/autocomplete/CompletionCellRenderer.java
@@ -17,6 +17,7 @@ import java.awt.Rectangle;
 import javax.swing.DefaultListCellRenderer;
 import javax.swing.Icon;
 import javax.swing.JList;
+import javax.swing.SwingUtilities;
 import javax.swing.plaf.basic.BasicHTML;
 import javax.swing.text.View;
 
@@ -58,6 +59,11 @@ public class CompletionCellRenderer extends 
DefaultListCellRenderer {
        private boolean showTypes;
 
        /**
+        * The color to use when rendering types in completion text.
+        */
+       private String typeColor;
+
+       /**
         * During rendering, whether the item being rendered is selected.
         */
        private boolean selected;
@@ -79,6 +85,14 @@ public class CompletionCellRenderer extends 
DefaultListCellRenderer {
        private Rectangle paintTextR;
 
        /**
+        * An optional delegate renderer (primarily for Substance).
+        */
+       private DefaultListCellRenderer delegate;
+
+       private static final String SUBSTANCE_RENDERER_CLASS_NAME =
+                       
"org.pushingpixels.substance.api.renderers.SubstanceDefaultListCellRenderer";
+
+       /**
         * Keeps the HTML descriptions from "wrapping" in the list, which cuts 
off
         * words.
         */
@@ -89,10 +103,63 @@ public class CompletionCellRenderer extends 
DefaultListCellRenderer {
         * Constructor.
         */
        public CompletionCellRenderer() {
-               //setDisplayFont(new Font("Monospaced", Font.PLAIN, 12));
-               setShowTypes(true);
-               paramColor = "#aa0077";
-               paintTextR = new Rectangle();
+               init();
+       }
+
+
+       /**
+        * Constructor.  This is primarily a hook for Substance, or any other
+        * Look and Feel whose renderers look drastically different than 
standard
+        * <code>DefaultListCellRenderer</code>s.  Everything except for the 
text
+        * rendering will be done by the delegate.  In almost all scenarios, you
+        * will want to use the no-argument constructor instead of this one.
+        *
+        * @param delegate The delegate renderer.
+        * @see #delegateToSubstanceRenderer()
+        */
+       public CompletionCellRenderer(DefaultListCellRenderer delegate) {
+               setDelegateRenderer(delegate);
+               init();
+       }
+
+
+       /**
+        * Returns a decent "parameter" color based on the current default
+        * foreground color.
+        *
+        * @return The parameter color to use.
+        */
+       private String createParamColor() {
+               return Util.isLightForeground(getForeground()) ? 
+                               
Util.getHexString(Util.getHyperlinkForeground()): "#aa0077";
+       }
+
+
+       /**
+        * Returns a decent "type" color based on the current default foreground
+        * color.
+        *
+        * @return The type color to use.
+        */
+       private String createTypeColor() {
+               return "#808080";
+       }
+
+
+       /**
+        * Attempts to delegate rendering to a Substance cell renderer.  This
+        * should only be called if Substance is known to be on the classpath.
+        *
+        * @throws Exception If Substance is not on the classpath, or some other
+        *         error occurs creating the Substance cell renderer.
+        * @see Util#getUseSubstanceRenderers()
+        * @see #setDelegateRenderer(DefaultListCellRenderer)
+        */
+       public void delegateToSubstanceRenderer() throws Exception {
+               Class clazz = Class.forName(SUBSTANCE_RENDERER_CLASS_NAME);
+               DefaultListCellRenderer delegate =
+                               (DefaultListCellRenderer)clazz.newInstance();
+               setDelegateRenderer(delegate);
        }
 
 
@@ -109,6 +176,17 @@ public class CompletionCellRenderer extends 
DefaultListCellRenderer {
 
 
        /**
+        * Returns the delegate renderer, or <code>null</code> if there is none.
+        *
+        * @return The delegate renderer.
+        * @see #setDelegateRenderer(DefaultListCellRenderer)
+        */
+       public DefaultListCellRenderer getDelegateRenderer() {
+               return delegate;
+       }
+
+
+       /**
         * Returns the font used when rendering completions.
         *
         * @return The font.  If this is <code>null</code>, then the default 
list
@@ -137,7 +215,7 @@ public class CompletionCellRenderer extends 
DefaultListCellRenderer {
                        setFont(font); // Overrides super's 
setFont(list.getFont()).
                }
                this.selected = selected;
-               this.realBG = altBG!=null && (index&1)==0 ? altBG : 
list.getBackground();
+               this.realBG = altBG!=null && (index&1)==1 ? altBG : 
list.getBackground();
 
                Completion c = (Completion)value;
                setIcon(c.getIcon());
@@ -162,7 +240,17 @@ public class CompletionCellRenderer extends 
DefaultListCellRenderer {
                        prepareForOtherCompletion(list, c, index, selected, 
hasFocus);
                }
 
-               if (!selected && (index&1)==0 && altBG!=null) {
+               // A delegate renderer might do its own alternate row striping
+               // (Substance does).
+               if (delegate!=null) {
+                       delegate.getListCellRendererComponent(list, getText(), 
index,
+                                       selected, hasFocus);
+                       delegate.setFont(getFont());
+                       delegate.setIcon(getIcon());
+                       return delegate;
+               }
+
+               if (!selected && (index&1)==1 && altBG!=null) {
                        setBackground(altBG);
                }
 
@@ -183,6 +271,15 @@ public class CompletionCellRenderer extends 
DefaultListCellRenderer {
        }
 
 
+       private void init() {
+               //setDisplayFont(new Font("Monospaced", Font.PLAIN, 12));
+               setShowTypes(true);
+               typeColor = createTypeColor();
+               paramColor = createParamColor();
+               paintTextR = new Rectangle();
+       }
+
+
        protected void paintComponent(Graphics g) {
 
                //super.paintComponent(g);
@@ -282,7 +379,7 @@ public class CompletionCellRenderer extends 
DefaultListCellRenderer {
                if (getShowTypes() && fc.getType()!=null) {
                        sb.append(" : ");
                        if (!selected) {
-                               sb.append("<font color='#808080'>");
+                               sb.append("<font 
color='").append(typeColor).append("'>");
                        }
                        sb.append(fc.getType());
                        if (!selected) {
@@ -355,7 +452,7 @@ public class CompletionCellRenderer extends 
DefaultListCellRenderer {
                if (definition!=null) {
                        sb.append(" - ");
                        if (!selected) {
-                               sb.append("<font color='#808080'>");
+                               sb.append("<font 
color='").append(typeColor).append("'>");
                        }
                        sb.append(definition);
                        if (!selected) {
@@ -386,7 +483,7 @@ public class CompletionCellRenderer extends 
DefaultListCellRenderer {
                if (getShowTypes() && vc.getType()!=null) {
                        sb.append(" : ");
                        if (!selected) {
-                               sb.append("<font color='#808080'>");
+                               sb.append("<font 
color='").append(typeColor).append("'>");
                        }
                        sb.append(vc.getType());
                        if (!selected) {
@@ -413,6 +510,22 @@ public class CompletionCellRenderer extends 
DefaultListCellRenderer {
 
 
        /**
+        * Sets the delegate renderer.  Most users will never use this method; 
it
+        * is primarily a hook for Substance and other Look and Feels whose
+        * renderers look drastically different from the standard
+        * <code>DefaultListCellRenderer</code>.
+        * 
+        * @param delegate The new delegate renderer.  If this is 
<code>null</code>,
+        *        the default rendering of this component is used.
+        * @see #getDelegateRenderer()
+        * @see #delegateToSubstanceRenderer()
+        */
+       public void setDelegateRenderer(DefaultListCellRenderer delegate) {
+               this.delegate = delegate;
+       }
+
+
+       /**
         * Sets the font to use when rendering completion items.
         *
         * @param font The font to use.  If this is <code>null</code>, then
@@ -442,6 +555,7 @@ public class CompletionCellRenderer extends 
DefaultListCellRenderer {
         * Sets the color to use for function arguments.
         *
         * @param color The color to use.  This is ignored if <code>null</code>.
+        * @see #setTypeColor(Color)
         */
        public void setParamColor(Color color) {
                if (color!=null) {
@@ -462,4 +576,33 @@ public class CompletionCellRenderer extends 
DefaultListCellRenderer {
        }
 
 
+       /**
+        * Sets the color to use for function/field types.  Note that if
+        * {@link #getShowTypes()} returns <code>false</code>, this property
+        * effectively does nothing.
+        *
+        * @param color The color to use for types.  This is ignored if
+        *        <code>null</code>.
+        * @see #setShowTypes(boolean)
+        * @see #setParamColor(Color)
+        */
+       public void setTypeColor(Color color) {
+               if (color!=null) {
+                       typeColor = Util.getHexString(color);
+               }
+       }
+
+
+       /**
+        * Overridden to update our delegate, if necessary.
+        */
+       public void updateUI() {
+               super.updateUI();
+               if (delegate!=null) {
+                       SwingUtilities.updateComponentTreeUI(delegate);
+               }
+               paramColor = createParamColor();
+       }
+
+
 }
\ No newline at end of file
diff --git a/src/org/fife/ui/autocomplete/TipUtil.java 
b/src/org/fife/ui/autocomplete/TipUtil.java
index 2caa0d4..7ee8664 100644
--- a/src/org/fife/ui/autocomplete/TipUtil.java
+++ b/src/org/fife/ui/autocomplete/TipUtil.java
@@ -159,6 +159,14 @@ class TipUtil {
                                "body { font-family: " + font.getFamily() +
                                                "; font-size: " + 
font.getSize() + "pt" +
                                                "; color: " + 
Util.getHexString(fg) + "; }");
+
+               // Always add link foreground rule.  Unfortunately these CSS 
rules
+               // stack each time the LaF is changed (how can we overwrite them
+               // without clearing out the important "standard" ones?).
+               Color linkFG = Util.getHyperlinkForeground();
+               doc.getStyleSheet().addRule(
+                               "a { color: " + Util.getHexString(linkFG) + "; 
}");
+
                URL url = TipUtil.class.getResource("bullet_black.png");
                if (url!=null) {
                        doc.getStyleSheet().addRule(
diff --git a/src/org/fife/ui/autocomplete/Util.java 
b/src/org/fife/ui/autocomplete/Util.java
index ceab7f5..c994b60 100644
--- a/src/org/fife/ui/autocomplete/Util.java
+++ b/src/org/fife/ui/autocomplete/Util.java
@@ -16,6 +16,8 @@ import java.awt.Rectangle;
 import java.lang.reflect.Method;
 import java.net.URI;
 import java.security.AccessControlException;
+import javax.swing.JLabel;
+import javax.swing.UIManager;
 
 import org.fife.ui.rsyntaxtextarea.PopupWindowDecorator;
 
@@ -29,6 +31,19 @@ import org.fife.ui.rsyntaxtextarea.PopupWindowDecorator;
 public class Util {
 
        /**
+        * If a system property is defined with this name and set, ignoring 
case,
+        * to <code>true</code>, this library will not attempt to use Substance
+        * renderers.  Otherwise, if a Substance Look and Feel is installed, we
+        * will attempt to use Substance cell renderers in all of our 
dropdowns.<p>
+        * 
+        * Note that we do not have a build dependency on Substance, so all 
access
+        * to Substance stuff is done via reflection.  We will fall back onto
+        * default renderers if something goes horribly wrong.
+        */
+       public static final String PROPERTY_DONT_USE_SUBSTANCE_RENDERERS =
+                       "org.fife.ui.autocomplete.DontUseSubstanceRenderers";
+
+       /**
         * If this system property is <code>true</code>, then even the "main" 
two
         * auto-complete windows will allow window decorations via
         * {@link PopupWindowDecorator}.  If this property is undefined or
@@ -39,6 +54,13 @@ public class Util {
        public static final String 
PROPERTY_ALLOW_DECORATED_AUTOCOMPLETE_WINDOWS =
                "org.fife.ui.autocomplete.allowDecoratedAutoCompleteWindows";
 
+       /**
+        * Used for the color of hyperlinks when a LookAndFeel uses light text
+        * against a dark background.
+        */
+       private static final Color LIGHT_HYPERLINK_FG = new Color(0xd8ffff);
+
+       private static final boolean useSubstanceRenderers;
        private static boolean desktopCreationAttempted;
        private static Object desktop;
        private static final Object LOCK_DESKTOP_CREATION = new Object();
@@ -158,6 +180,28 @@ public class Util {
 
 
        /**
+        * Returns the color to use for hyperlink-style components.  This method
+        * will return <code>Color.blue</code> unless it appears that the 
current
+        * LookAndFeel uses light text on a dark background, in which case a
+        * brighter alternative is returned.
+        *
+        * @return The color to use for hyperlinks.
+        */
+       static final Color getHyperlinkForeground() {
+
+               // This property is defined by all standard LaFs, even Nimbus 
(!),
+               // but you never know what crazy LaFs there are...
+               Color fg = UIManager.getColor("Label.foreground");
+               if (fg==null) {
+                       fg = new JLabel().getForeground();
+               }
+
+               return isLightForeground(fg) ? LIGHT_HYPERLINK_FG : Color.blue;
+
+       }
+
+
+       /**
         * Returns the screen coordinates for the monitor that contains the
         * specified point.  This is useful for setups with multiple monitors,
         * to ensure that popup windows are positioned properly.
@@ -202,6 +246,32 @@ public class Util {
 
 
        /**
+        * Returns whether we should attempt to use Substance cell renderers and
+        * styles for things such as completion choices, if a Substance Look and
+        * Feel is installed.  If this is <code>false</code>, we'll use our
+        * standard rendering for completions, even when Substance is being 
used.
+        *
+        * @return Whether to use Substance renderers if Substance is installed.
+        */
+       public static boolean getUseSubstanceRenderers() {
+               return useSubstanceRenderers;
+       }
+
+
+       /**
+        * Returns whether the specified color is "light" to use as a 
foreground.
+        * Colors that return <code>true</code> indicate that the current Look 
and
+        * Feel probably uses light text colors on a dark background.
+        *
+        * @param fg The foreground color.
+        * @return Whether it is a "light" foreground color.
+        */
+       public static final boolean isLightForeground(Color fg) {
+               return fg.getRed()>0xa0 && fg.getGreen()>0xa0 && 
fg.getBlue()>0xa0;
+       }
+
+
+       /**
         * Returns whether <code>str</code> starts with <code>start</code>,
         * ignoring case.
         *
@@ -226,4 +296,17 @@ public class Util {
        }
 
 
+       static {
+
+               boolean use = true;
+               try {
+                       use = 
!Boolean.getBoolean(PROPERTY_DONT_USE_SUBSTANCE_RENDERERS);
+               } catch (AccessControlException ace) { // We're in an applet.
+                       use = true;
+               }
+               useSubstanceRenderers = use;
+
+       }
+
+
 }
\ No newline at end of file

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-java/autocomplete.git

_______________________________________________
pkg-java-commits mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-java-commits

Reply via email to