"debugfocus" is more consistent with "debugpaint", which is nice. Also, as a 
user, I think I might find it odd that I need to specify a color when really I 
just want the debug focus behavior. Also, as Sandro pointed out, any hard-coded 
color may work well in some schemes but not in others.

To avoid that issue, you could draw the focus outline in XOR mode. It might not 
look as nice as a color, though.

On Sep 24, 2010, at 12:13 PM, Chris Bartlett wrote:

> OK, I am about to revert Component and push everything into
> ApplicationContext.
> 
> Do really you want me to remove the debugfocuscolor property and switch to a
> boolean debugfocus property?
> For the sake of ~10 LOC, I thought there was value to be had in being able
> to simply select an alternative color.
> Your call.
> 
> Chris
> 
> On 24 September 2010 22:26, Greg Brown <[email protected]> wrote:
> 
>> I was thinking of something more internal that wouldn't require public
>> Component API changes. For example, in ApplicationContext.DisplayHost, if
>> the "debugfocus" system property exists and is set to true, all we'd need to
>> do is create a ComponentClassListener and set it via the static
>> Component#getComponentClassListeners() method. Then we could attach/remove a
>> focus decorator in the focusedComponentChanged() event.
>> 
>> The reason that I don't think this belongs in the public Component API is
>> because it is a) a debug feature and b) up to the skin to determine how
>> focus state should be represented, not the component or the application.
>> Making this public implies otherwise.
>> 
>> I personally wouldn't worry about allowing the caller to specify a color.
>> I'd just pick something visible (for example, old versions of the Flash
>> player used to draw a yellow rectangle around the focused element).
>> 
>> G
>> 
>> On Sep 24, 2010, at 9:46 AM, [email protected] wrote:
>> 
>>> Author: cbartlett
>>> Date: Fri Sep 24 13:46:42 2010
>>> New Revision: 1000869
>>> 
>>> URL: http://svn.apache.org/viewvc?rev=1000869&view=rev
>>> Log:
>>> Resolve PIVOT-607
>>> Added static getFocusDecorator & setFocusDecorator methods to & Component
>>> ApplicationContext now looks for a 'org.apache.pivot.wtk.debugfocuscolor'
>> system property with a case insensitive value of 'red', 'green' or 'blue'.
>>> 
>>> Modified:
>>>   pivot/trunk/wtk/src/org/apache/pivot/wtk/ApplicationContext.java
>>>   pivot/trunk/wtk/src/org/apache/pivot/wtk/Component.java
>>> 
>>> Modified:
>> pivot/trunk/wtk/src/org/apache/pivot/wtk/ApplicationContext.java
>>> URL:
>> http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/ApplicationContext.java?rev=1000869&r1=1000868&r2=1000869&view=diff
>>> 
>> ==============================================================================
>>> --- pivot/trunk/wtk/src/org/apache/pivot/wtk/ApplicationContext.java
>> (original)
>>> +++ pivot/trunk/wtk/src/org/apache/pivot/wtk/ApplicationContext.java Fri
>> Sep 24 13:46:42 2010
>>> @@ -17,6 +17,7 @@
>>> package org.apache.pivot.wtk;
>>> 
>>> import java.awt.AWTEvent;
>>> +import java.awt.Color;
>>> import java.awt.Graphics;
>>> import java.awt.Graphics2D;
>>> import java.awt.GraphicsConfiguration;
>>> @@ -61,6 +62,7 @@ import org.apache.pivot.serialization.Se
>>> import org.apache.pivot.util.Version;
>>> import org.apache.pivot.wtk.Component.DecoratorSequence;
>>> import org.apache.pivot.wtk.effects.Decorator;
>>> +import org.apache.pivot.wtk.effects.ShadeDecorator;
>>> 
>>> /**
>>> * Base class for application contexts.
>>> @@ -297,6 +299,26 @@ public abstract class ApplicationContext
>>>                // No-op
>>>            }
>>> 
>>> +            try {
>>> +                String property =
>> System.getProperty("org.apache.pivot.wtk.debugfocuscolor");
>>> +                if (property != null) {
>>> +                    property = property.trim().toLowerCase();
>>> +                    Color focusColor = null;
>>> +                    if ("red".equals(property)) {
>>> +                        focusColor = Color.RED;
>>> +                    } else if ("green".equals(property)) {
>>> +                        focusColor = Color.GREEN;
>>> +                    } else if ("blue".equals(property)) {
>>> +                        focusColor = Color.BLUE;
>>> +                    }
>>> +                    if (focusColor != null) {
>>> +                        Component.setFocusDecorator(new
>> ShadeDecorator(0.2f, focusColor));
>>> +                    }
>>> +                }
>>> +            } catch (SecurityException ex) {
>>> +                // No-op
>>> +            }
>>> +
>>>            // Add native drop support
>>>            new java.awt.dnd.DropTarget(this, dropTargetListener);
>>> 
>>> 
>>> Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/Component.java
>>> URL:
>> http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/Component.java?rev=1000869&r1=1000868&r2=1000869&view=diff
>>> 
>> ==============================================================================
>>> --- pivot/trunk/wtk/src/org/apache/pivot/wtk/Component.java (original)
>>> +++ pivot/trunk/wtk/src/org/apache/pivot/wtk/Component.java Fri Sep 24
>> 13:46:42 2010
>>> @@ -676,6 +676,28 @@ public abstract class Component implemen
>>>    // The component that currently has the focus
>>>    private static Component focusedComponent = null;
>>> 
>>> +    // Decorator to apply to the focused component
>>> +    private static Decorator focusDecorator = null;
>>> +
>>> +    // Focus change listener to manage adding & removing of
>> focusDecorator
>>> +    private static final ComponentClassListener FOCUS_CHANGE_LISTENER =
>> new ComponentClassListener() {
>>> +        @Override
>>> +        public void focusedComponentChanged(Component
>> previousFocusedComponent) {
>>> +            Decorator decorator = Component.getFocusDecorator();
>>> +            if (decorator != null) {
>>> +                if (previousFocusedComponent != null
>>> +                    &&
>> previousFocusedComponent.getDecorators().indexOf(decorator) > -1) {
>>> +
>> previousFocusedComponent.getDecorators().remove(decorator);
>>> +                }
>>> +                Component focusedComponent =
>> Component.getFocusedComponent();
>>> +                if (focusedComponent != null
>>> +                    &&
>> focusedComponent.getDecorators().indexOf(decorator) == -1) {
>>> +                    focusedComponent.getDecorators().add(decorator);
>>> +                }
>>> +            }
>>> +        }
>>> +    };
>>> +
>>>    // Typed and named styles
>>>    private static HashMap<Class<? extends Component>, Map<String, ?>>
>> typedStyles =
>>>        new HashMap<Class<? extends Component>, Map<String,?>>();
>>> @@ -2430,6 +2452,40 @@ public abstract class Component implemen
>>>    }
>>> 
>>>    /**
>>> +     * Returns the Decorator which is applied to all focused Components.
>>> +     *
>>> +     * @return The Decorator, or <tt>null</tt> if no Decorator has been
>> set.
>>> +     */
>>> +    public static Decorator getFocusDecorator() {
>>> +        return focusDecorator;
>>> +    }
>>> +
>>> +    /**
>>> +     * Set the Decorator to be applied to all focused Components.
>>> +     *
>>> +     * @param focusDecorator
>>> +     */
>>> +    public static void setFocusDecorator(Decorator focusDecorator) {
>>> +        Component focusedComponent = getFocusedComponent();
>>> +        Decorator previousFocusDecorator = Component.focusDecorator;
>>> +        Component.focusDecorator = focusDecorator;
>>> +        if (focusedComponent != null) {
>>> +            if (previousFocusDecorator != null) {
>>> +
>> focusedComponent.getDecorators().remove(previousFocusDecorator);
>>> +            }
>>> +            if (focusDecorator != null) {
>>> +                focusedComponent.getDecorators().add(focusDecorator);
>>> +            }
>>> +        }
>>> +        if (focusDecorator == null && previousFocusDecorator != null) {
>>> +
>> Component.getComponentClassListeners().remove(FOCUS_CHANGE_LISTENER);
>>> +        }
>>> +        if (focusDecorator != null && previousFocusDecorator == null) {
>>> +
>> Component.getComponentClassListeners().add(FOCUS_CHANGE_LISTENER);
>>> +        }
>>> +    }
>>> +
>>> +    /**
>>>     * Copies bound values from the bind context to the component. This
>>>     * functionality must be provided by the subclass; the base
>> implementation
>>>     * is a no-op.
>>> 
>>> 
>> 
>> 

Reply via email to