You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by tv...@apache.org on 2009/03/26 00:12:17 UTC

svn commit: r758461 [38/47] - in /incubator/pivot/branches: ./ 1.1/ 1.1/charts-test/ 1.1/charts-test/src/ 1.1/charts-test/src/pivot/ 1.1/charts-test/src/pivot/charts/ 1.1/charts-test/src/pivot/charts/test/ 1.1/charts/ 1.1/charts/lib/ 1.1/charts/src/ 1....

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraLinkButtonSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraLinkButtonSkin.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraLinkButtonSkin.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraLinkButtonSkin.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.skin.terra;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+
+import pivot.wtk.Button;
+import pivot.wtk.Dimensions;
+import pivot.wtk.LinkButton;
+import pivot.wtk.Theme;
+import pivot.wtk.skin.LinkButtonSkin;
+
+/**
+ * Terra link button skin.
+ *
+ * @author gbrown
+ */
+public class TerraLinkButtonSkin extends LinkButtonSkin {
+    private Font font;
+    private Color color;
+    private Color disabledColor;
+
+    public TerraLinkButtonSkin() {
+        TerraTheme theme = (TerraTheme)Theme.getTheme();
+        font = theme.getFont();
+        color = theme.getColor(13);
+        disabledColor = theme.getColor(7);
+    }
+
+    public int getPreferredWidth(int height) {
+        LinkButton linkButton = (LinkButton)getComponent();
+
+        Button.DataRenderer dataRenderer = linkButton.getDataRenderer();
+        dataRenderer.render(linkButton.getButtonData(), linkButton, false);
+
+        return dataRenderer.getPreferredWidth(height);
+    }
+
+    public int getPreferredHeight(int width) {
+        LinkButton linkButton = (LinkButton)getComponent();
+
+        Button.DataRenderer dataRenderer = linkButton.getDataRenderer();
+        dataRenderer.render(linkButton.getButtonData(), linkButton, false);
+
+        return dataRenderer.getPreferredHeight(width);
+    }
+
+    public Dimensions getPreferredSize() {
+        LinkButton linkButton = (LinkButton)getComponent();
+
+        Button.DataRenderer dataRenderer = linkButton.getDataRenderer();
+        dataRenderer.render(linkButton.getButtonData(), linkButton, false);
+
+        return dataRenderer.getPreferredSize();
+    }
+
+    public void paint(Graphics2D graphics) {
+        LinkButton linkButton = (LinkButton)getComponent();
+        int width = getWidth();
+        int height = getHeight();
+
+        Button.DataRenderer dataRenderer = linkButton.getDataRenderer();
+        dataRenderer.render(linkButton.getButtonData(), linkButton, highlighted);
+        dataRenderer.setSize(width, height);
+
+        dataRenderer.paint(graphics);
+    }
+
+    public Font getFont() {
+        return font;
+    }
+
+    public void setFont(Font font) {
+        if (font == null) {
+            throw new IllegalArgumentException("font is null.");
+        }
+
+        this.font = font;
+        invalidateComponent();
+    }
+
+    public final void setFont(String font) {
+        if (font == null) {
+            throw new IllegalArgumentException("font is null.");
+        }
+
+        setFont(Font.decode(font));
+    }
+
+    public Color getColor() {
+        return color;
+    }
+
+    public void setColor(Color color) {
+        if (color == null) {
+            throw new IllegalArgumentException("color is null.");
+        }
+
+        this.color = color;
+        repaintComponent();
+    }
+
+    public final void setColor(String color) {
+        if (color == null) {
+            throw new IllegalArgumentException("color is null.");
+        }
+
+        setColor(decodeColor(color));
+    }
+
+    public Color getDisabledColor() {
+        return disabledColor;
+    }
+
+    public void setDisabledColor(Color disabledColor) {
+        if (disabledColor == null) {
+            throw new IllegalArgumentException("disabledColor is null.");
+        }
+
+        this.disabledColor = disabledColor;
+        repaintComponent();
+    }
+
+    public final void setDisabledColor(String disabledColor) {
+        if (disabledColor == null) {
+            throw new IllegalArgumentException("disabledColor is null.");
+        }
+
+        setDisabledColor(decodeColor(disabledColor));
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraListButtonSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraListButtonSkin.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraListButtonSkin.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraListButtonSkin.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,602 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.skin.terra;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.GradientPaint;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.GeneralPath;
+
+import pivot.collections.Dictionary;
+import pivot.collections.List;
+import pivot.util.Vote;
+import pivot.wtk.Border;
+import pivot.wtk.Button;
+import pivot.wtk.Dimensions;
+import pivot.wtk.Display;
+import pivot.wtk.Insets;
+import pivot.wtk.ListButton;
+import pivot.wtk.ListView;
+import pivot.wtk.Panorama;
+import pivot.wtk.Bounds;
+import pivot.wtk.Theme;
+import pivot.wtk.Window;
+import pivot.wtk.WindowStateListener;
+import pivot.wtk.effects.Transition;
+import pivot.wtk.effects.TransitionListener;
+import pivot.wtk.skin.ListButtonSkin;
+
+/**
+ * Terra list button skin.
+ *
+ * @author gbrown
+ */
+public class TerraListButtonSkin extends ListButtonSkin {
+    private Panorama listViewPanorama;
+    private Border listViewBorder;
+
+    private WindowStateListener listViewPopupStateListener = new WindowStateListener() {
+        private boolean focusButtonOnClose = true;
+
+        public Vote previewWindowOpen(Window window, Display display) {
+            return Vote.APPROVE;
+        }
+
+        public void windowOpenVetoed(Window window, Vote reason) {
+            // No-op
+        }
+
+        public void windowOpened(Window window) {
+            focusButtonOnClose = true;
+        }
+
+        public Vote previewWindowClose(final Window window) {
+            Vote vote = Vote.APPROVE;
+
+            if (closeTransition == null) {
+                closeTransition = new FadeTransition(window,
+                    CLOSE_TRANSITION_DURATION, CLOSE_TRANSITION_RATE);
+
+                closeTransition.start(new TransitionListener() {
+                    public void transitionCompleted(Transition transition) {
+                        focusButtonOnClose = window.containsFocus();
+                        window.close();
+                    }
+                });
+
+                vote = Vote.DEFER;
+            } else {
+                vote = (closeTransition.isRunning()) ? Vote.DEFER : Vote.APPROVE;
+            }
+
+            return vote;
+        }
+
+        public void windowCloseVetoed(Window window, Vote reason) {
+            if (reason == Vote.DENY
+                && closeTransition != null) {
+                closeTransition.stop();
+                closeTransition = null;
+            }
+        }
+
+        public void windowClosed(Window window, Display display) {
+            closeTransition = null;
+            if (focusButtonOnClose) {
+                getComponent().requestFocus();
+            }
+        }
+    };
+
+    private Font font;
+    private Color color;
+    private Color disabledColor;
+    private Color backgroundColor;
+    private Color disabledBackgroundColor;
+    private Color borderColor;
+    private Color disabledBorderColor;
+    private Insets padding;
+    private int listSize = -1;
+
+    // Derived colors
+    private Color bevelColor;
+    private Color pressedBevelColor;
+    private Color disabledBevelColor;
+
+    private Transition closeTransition = null;
+
+    private static final int TRIGGER_WIDTH = 14;
+
+    private static final int CLOSE_TRANSITION_DURATION = 250;
+    private static final int CLOSE_TRANSITION_RATE = 30;
+
+    public TerraListButtonSkin() {
+        TerraTheme theme = (TerraTheme)Theme.getTheme();
+
+        font = theme.getFont();
+        color = theme.getColor(1);
+        disabledColor = theme.getColor(7);
+        backgroundColor = theme.getColor(10);
+        disabledBackgroundColor = theme.getColor(10);
+        borderColor = theme.getColor(7);
+        disabledBorderColor = theme.getColor(7);
+        padding = new Insets(2, 3, 2, 3);
+
+        // Set the derived colors
+        bevelColor = TerraTheme.brighten(backgroundColor);
+        pressedBevelColor = TerraTheme.darken(backgroundColor);
+        disabledBevelColor = disabledBackgroundColor;
+
+        listViewPopup.getWindowStateListeners().add(listViewPopupStateListener);
+
+        // Create the panorama and border
+        listViewPanorama = new Panorama(listView);
+        listViewPanorama.getStyles().put("buttonBackgroundColor",
+            listView.getStyles().get("backgroundColor"));
+        listViewPanorama.getStyles().put("alwaysShowScrollButtons", true);
+
+        listViewBorder = new Border(listViewPanorama);
+        listViewBorder.getStyles().put("padding", 0);
+        listViewBorder.getStyles().put("color", borderColor);
+
+        // Set the popup content
+        listViewPopup.setContent(listViewBorder);
+    }
+
+    @SuppressWarnings("unchecked")
+    public int getPreferredWidth(int height) {
+        ListButton listButton = (ListButton)getComponent();
+        List<?> listData = listButton.getListData();
+
+        Button.DataRenderer dataRenderer = listButton.getDataRenderer();
+
+        // Include padding in constraint
+        if (height != -1) {
+            height = Math.max(height - (padding.top + padding.bottom + 2), 0);
+        }
+
+        // Determine the preferred width of the current button data
+        dataRenderer.render(listButton.getButtonData(),
+            listButton, false);
+        int preferredWidth = dataRenderer.getPreferredWidth(-1);
+
+        // The preferred width of the button is the max. width of the rendered
+        // content plus padding and the trigger width
+        for (Object item : listData) {
+            dataRenderer.render(item, listButton, false);
+            preferredWidth = Math.max(preferredWidth, dataRenderer.getPreferredWidth(-1));
+        }
+
+        preferredWidth += TRIGGER_WIDTH + padding.left + padding.right + 2;
+
+        return preferredWidth;
+    }
+
+    public int getPreferredHeight(int width) {
+        ListButton listButton = (ListButton)getComponent();
+        Button.DataRenderer dataRenderer = listButton.getDataRenderer();
+
+        dataRenderer.render(listButton.getButtonData(), listButton, false);
+
+        int preferredHeight = dataRenderer.getPreferredHeight(-1)
+            + padding.top + padding.bottom + 2;
+
+        return preferredHeight;
+    }
+
+    public Dimensions getPreferredSize() {
+        // TODO Optimize by performing calcuations locally
+        return new Dimensions(getPreferredWidth(-1), getPreferredHeight(-1));
+    }
+
+    public void layout() {
+        // No-op
+    }
+
+    public void paint(Graphics2D graphics) {
+        ListButton listButton = (ListButton)getComponent();
+
+        int width = getWidth();
+        int height = getHeight();
+
+        Color backgroundColor = null;
+        Color bevelColor = null;
+        Color borderColor = null;
+
+        if (listButton.isEnabled()) {
+            backgroundColor = this.backgroundColor;
+            bevelColor = (pressed
+        		|| (listViewPopup.isOpen() && closeTransition == null)) ? pressedBevelColor : this.bevelColor;
+            borderColor = this.borderColor;
+        } else {
+            backgroundColor = disabledBackgroundColor;
+            bevelColor = disabledBevelColor;
+            borderColor = disabledBorderColor;
+        }
+
+        graphics.setStroke(new BasicStroke());
+
+        // Paint the background
+        graphics.setPaint(new GradientPaint(width / 2, 0, bevelColor,
+            width / 2, height / 2, backgroundColor));
+        graphics.fillRect(0, 0, width, height);
+
+        // Paint the border
+        graphics.setPaint(borderColor);
+
+        Bounds contentBounds = new Bounds(0, 0,
+            Math.max(width - TRIGGER_WIDTH - 1, 0), Math.max(height - 1, 0));
+        graphics.drawRect(contentBounds.x, contentBounds.y, contentBounds.width, contentBounds.height);
+
+        Bounds triggerBounds = new Bounds(Math.max(width - TRIGGER_WIDTH - 1, 0), 0,
+            TRIGGER_WIDTH, Math.max(height - 1, 0));
+        graphics.drawRect(triggerBounds.x, triggerBounds.y, triggerBounds.width, triggerBounds.height);
+
+        // Paint the content
+        Button.DataRenderer dataRenderer = listButton.getDataRenderer();
+        dataRenderer.render(listButton.getButtonData(), listButton, false);
+        dataRenderer.setSize(Math.max(contentBounds.width - (padding.left + padding.right + 2) + 1, 0),
+            Math.max(contentBounds.height - (padding.top + padding.bottom + 2) + 1, 0));
+
+        Graphics2D contentGraphics = (Graphics2D)graphics.create();
+        contentGraphics.translate(padding.left + 1, padding.top + 1);
+        contentGraphics.clipRect(0, 0, dataRenderer.getWidth(), dataRenderer.getHeight());
+        dataRenderer.paint(contentGraphics);
+        contentGraphics.dispose();
+
+        // Paint the focus state
+        if (listButton.isFocused()) {
+            BasicStroke dashStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND,
+                BasicStroke.JOIN_ROUND, 1.0f, new float[] {0.0f, 2.0f}, 0.0f);
+
+            graphics.setStroke(dashStroke);
+            graphics.setColor(borderColor);
+
+            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                RenderingHints.VALUE_ANTIALIAS_ON);
+
+            graphics.drawRect(2, 2, Math.max(contentBounds.width - 4, 0),
+                Math.max(contentBounds.height - 4, 0));
+
+            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                RenderingHints.VALUE_ANTIALIAS_OFF);
+        }
+
+        // Paint the trigger
+        GeneralPath triggerIconShape = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
+        triggerIconShape.moveTo(0, 0);
+        triggerIconShape.lineTo(3, 3);
+        triggerIconShape.lineTo(6, 0);
+        triggerIconShape.closePath();
+
+        Graphics2D triggerGraphics = (Graphics2D)graphics.create();
+        triggerGraphics.setStroke(new BasicStroke(0));
+        triggerGraphics.setPaint(color);
+
+        int tx = triggerBounds.x + Math.round((triggerBounds.width
+            - triggerIconShape.getBounds().width) / 2f);
+        int ty = triggerBounds.y + Math.round((triggerBounds.height
+            - triggerIconShape.getBounds().height) / 2f);
+        triggerGraphics.translate(tx, ty);
+
+        triggerGraphics.draw(triggerIconShape);
+        triggerGraphics.fill(triggerIconShape);
+
+        triggerGraphics.dispose();
+    }
+
+    public Font getFont() {
+        return font;
+    }
+
+    public void setFont(Font font) {
+        if (font == null) {
+            throw new IllegalArgumentException("font is null.");
+        }
+
+        this.font = font;
+        invalidateComponent();
+    }
+
+    public final void setFont(String font) {
+        if (font == null) {
+            throw new IllegalArgumentException("font is null.");
+        }
+
+        setFont(Font.decode(font));
+    }
+
+    public Color getColor() {
+        return color;
+    }
+
+    public void setColor(Color color) {
+        if (color == null) {
+            throw new IllegalArgumentException("color is null.");
+        }
+
+        this.color = color;
+        repaintComponent();
+    }
+
+    public final void setColor(String color) {
+        if (color == null) {
+            throw new IllegalArgumentException("color is null.");
+        }
+
+        setColor(decodeColor(color));
+    }
+
+    public Color getDisabledColor() {
+        return disabledColor;
+    }
+
+    public void setDisabledColor(Color disabledColor) {
+        if (disabledColor == null) {
+            throw new IllegalArgumentException("disabledColor is null.");
+        }
+
+        this.disabledColor = disabledColor;
+        repaintComponent();
+    }
+
+    public final void setDisabledColor(String disabledColor) {
+        if (disabledColor == null) {
+            throw new IllegalArgumentException("disabledColor is null.");
+        }
+
+        setDisabledColor(decodeColor(disabledColor));
+    }
+
+    public Color getBackgroundColor() {
+        return backgroundColor;
+    }
+
+    public void setBackgroundColor(Color backgroundColor) {
+        if (backgroundColor == null) {
+            throw new IllegalArgumentException("backgroundColor is null.");
+        }
+
+        this.backgroundColor = backgroundColor;
+        bevelColor = TerraTheme.brighten(backgroundColor);
+        pressedBevelColor = TerraTheme.darken(backgroundColor);
+        repaintComponent();
+    }
+
+    public final void setBackgroundColor(String backgroundColor) {
+        if (backgroundColor == null) {
+            throw new IllegalArgumentException("backgroundColor is null.");
+        }
+
+        setBackgroundColor(decodeColor(backgroundColor));
+    }
+
+    public Color getDisabledBackgroundColor() {
+        return disabledBackgroundColor;
+    }
+
+    public void setDisabledBackgroundColor(Color disabledBackgroundColor) {
+        if (disabledBackgroundColor == null) {
+            throw new IllegalArgumentException("disabledBackgroundColor is null.");
+        }
+
+        this.disabledBackgroundColor = disabledBackgroundColor;
+        disabledBevelColor = disabledBackgroundColor;
+        repaintComponent();
+    }
+
+    public final void setDisabledBackgroundColor(String disabledBackgroundColor) {
+        if (disabledBackgroundColor == null) {
+            throw new IllegalArgumentException("disabledBackgroundColor is null.");
+        }
+
+        setDisabledBackgroundColor(decodeColor(disabledBackgroundColor));
+    }
+
+    public Color getBorderColor() {
+        return borderColor;
+    }
+
+    public void setBorderColor(Color borderColor) {
+        if (borderColor == null) {
+            throw new IllegalArgumentException("borderColor is null.");
+        }
+
+        this.borderColor = borderColor;
+        listViewBorder.getStyles().put("color", borderColor);
+        repaintComponent();
+    }
+
+    public final void setBorderColor(String borderColor) {
+        if (borderColor == null) {
+            throw new IllegalArgumentException("borderColor is null.");
+        }
+
+        setBorderColor(decodeColor(borderColor));
+    }
+
+    public Color getDisabledBorderColor() {
+        return disabledBorderColor;
+    }
+
+    public void setDisabledBorderColor(Color disabledBorderColor) {
+        if (disabledBorderColor == null) {
+            throw new IllegalArgumentException("disabledBorderColor is null.");
+        }
+
+        this.disabledBorderColor = disabledBorderColor;
+        repaintComponent();
+    }
+
+    public final void setDisabledBorderColor(String disabledBorderColor) {
+        if (disabledBorderColor == null) {
+            throw new IllegalArgumentException("disabledBorderColor is null.");
+        }
+
+        setDisabledBorderColor(decodeColor(disabledBorderColor));
+    }
+
+    public Insets getPadding() {
+        return padding;
+    }
+
+    public void setPadding(Insets padding) {
+        if (padding == null) {
+            throw new IllegalArgumentException("padding is null.");
+        }
+
+        this.padding = padding;
+        invalidateComponent();
+    }
+
+    public final void setPadding(Dictionary<String, ?> padding) {
+        if (padding == null) {
+            throw new IllegalArgumentException("padding is null.");
+        }
+
+        setPadding(new Insets(padding));
+    }
+
+    public final void setPadding(int padding) {
+        setPadding(new Insets(padding));
+    }
+
+    public final void setPadding(Number padding) {
+        if (padding == null) {
+            throw new IllegalArgumentException("padding is null.");
+        }
+
+        setPadding(padding.intValue());
+    }
+
+    public int getListSize() {
+    	return listSize;
+    }
+
+    public void setListSize(int listSize) {
+    	if (listSize < -1) {
+    		throw new IllegalArgumentException("Invalid list size.");
+    	}
+
+    	this.listSize = listSize;
+    }
+
+    public Object getListFont() {
+        return listView.getStyles().get("font");
+    }
+
+    public void setListFont(Object listFont) {
+        listView.getStyles().put("font", listFont);
+    }
+
+    public Object getListColor() {
+        return listView.getStyles().get("color");
+    }
+
+    public void setListColor(Object listColor) {
+        listView.getStyles().put("color", listColor);
+    }
+
+    public Object getListDisabledColor() {
+        return listView.getStyles().get("disabledColor");
+    }
+
+    public void setListDisabledColor(Object listDisabledColor) {
+        listView.getStyles().put("disabledColor", listDisabledColor);
+    }
+
+    public Object getListBackgroundColor() {
+        return listView.getStyles().get("backgroundColor");
+    }
+
+    public void setListBackgroundColor(Object listBackgroundColor) {
+        listView.getStyles().put("backgroundColor", listBackgroundColor);
+        listViewPanorama.getStyles().put("buttonBackgroundColor", listBackgroundColor);
+    }
+
+    public Object getListSelectionColor() {
+        return listView.getStyles().get("selectionColor");
+    }
+
+    public void setListSelectionColor(Object listSelectionColor) {
+        listView.getStyles().put("selectionColor", listSelectionColor);
+    }
+
+    public Object getListSelectionBackgroundColor() {
+        return listView.getStyles().get("selectionBackgroundColor");
+    }
+
+    public void setListSelectionBackgroundColor(Object listSelectionBackgroundColor) {
+        listView.getStyles().put("selectionBackgroundColor", listSelectionBackgroundColor);
+    }
+
+    public Object getListInactiveSelectionColor() {
+        return listView.getStyles().get("inactiveSelectionColor");
+    }
+
+    public void setListInactiveSelectionColor(Object listInactiveSelectionColor) {
+        listView.getStyles().put("inactiveSelectionColor", listInactiveSelectionColor);
+    }
+
+    public Object getListInactiveSelectionBackgroundColor() {
+        return listView.getStyles().get("inactiveSelectionBackgroundColor");
+    }
+
+    public void setListInactiveSelectionBackgroundColor(Object listInactiveSelectionBackgroundColor) {
+        listView.getStyles().put("inactiveSelectionBackgroundColor", listInactiveSelectionBackgroundColor);
+    }
+
+    public Object getListHighlightColor() {
+        return listView.getStyles().get("highlightColor");
+    }
+
+    public void setListHighlightColor(Object listHighlightColor) {
+        listView.getStyles().put("highlightColor", listHighlightColor);
+    }
+
+    public Object getListHighlightBackgroundColor() {
+        return listView.getStyles().get("highlightBackgroundColor");
+    }
+
+    public void setListHighlightBackgroundColor(Object listHighlightBackgroundColor) {
+        listView.getStyles().put("highlightBackgroundColor", listHighlightBackgroundColor);
+    }
+
+    @Override
+    public void buttonPressed(Button button) {
+    	if (!listViewPopup.isOpen()) {
+        	if (listSize == -1) {
+        		listViewBorder.setPreferredHeight(-1);
+        	} else {
+        		if (!listViewBorder.isPreferredHeightSet()) {
+            		ListView.ItemRenderer itemRenderer = listView.getItemRenderer();
+            		int height = itemRenderer.getPreferredHeight(-1) * listSize + 2;
+
+            		if (listViewBorder.getPreferredHeight() > height) {
+            			listViewBorder.setPreferredHeight(height);
+            		} else {
+            			listViewBorder.setPreferredHeight(-1);
+            		}
+        		}
+        	}
+    	}
+
+    	super.buttonPressed(button);
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraListViewSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraListViewSkin.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraListViewSkin.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraListViewSkin.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,833 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.skin.terra;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+
+import pivot.collections.ArrayList;
+import pivot.collections.List;
+import pivot.collections.Sequence;
+import pivot.wtk.Checkbox;
+import pivot.wtk.Component;
+import pivot.wtk.Dimensions;
+import pivot.wtk.Insets;
+import pivot.wtk.Keyboard;
+import pivot.wtk.ListView;
+import pivot.wtk.ListViewItemStateListener;
+import pivot.wtk.ListViewListener;
+import pivot.wtk.ListViewItemListener;
+import pivot.wtk.ListViewSelectionListener;
+import pivot.wtk.Mouse;
+import pivot.wtk.Bounds;
+import pivot.wtk.Span;
+import pivot.wtk.Theme;
+import pivot.wtk.skin.ComponentSkin;
+
+/**
+ * List view skin.
+ * <p>
+ * NOTE This skin assumes a fixed renderer height.
+ *
+ * @author gbrown
+ */
+public class TerraListViewSkin extends ComponentSkin implements ListView.Skin,
+    ListViewListener, ListViewItemListener, ListViewItemStateListener,
+    ListViewSelectionListener {
+    private Font font;
+    private Color color;
+    private Color disabledColor;
+    private Color backgroundColor;
+    private Color selectionColor;
+    private Color selectionBackgroundColor;
+    private Color inactiveSelectionColor;
+    private Color inactiveSelectionBackgroundColor;
+    private Color highlightColor;
+    private Color highlightBackgroundColor;
+    private boolean showHighlight;
+    private Insets checkboxPadding = new Insets(2, 2, 2, 0);
+
+    private int highlightedIndex = -1;
+    private int editIndex = -1;
+
+    private static final Checkbox CHECKBOX = new Checkbox();
+
+    static {
+    	CHECKBOX.setSize(CHECKBOX.getPreferredSize());
+    }
+
+    public TerraListViewSkin() {
+        TerraTheme theme = (TerraTheme)Theme.getTheme();
+        font = theme.getFont();
+        color = theme.getColor(1);
+        disabledColor = theme.getColor(7);
+        backgroundColor = theme.getColor(4);
+        selectionColor = theme.getColor(4);
+        selectionBackgroundColor = theme.getColor(19);
+        inactiveSelectionColor = theme.getColor(1);
+        inactiveSelectionBackgroundColor = theme.getColor(9);
+        highlightColor = theme.getColor(1);
+        highlightBackgroundColor = theme.getColor(10);
+        showHighlight = true;
+    }
+
+    public void install(Component component) {
+        super.install(component);
+
+        ListView listView = (ListView)component;
+        listView.getListViewListeners().add(this);
+        listView.getListViewItemListeners().add(this);
+        listView.getListViewItemStateListeners().add(this);
+        listView.getListViewSelectionListeners().add(this);
+    }
+
+    public void uninstall() {
+        ListView listView = (ListView)getComponent();
+        listView.getListViewListeners().remove(this);
+        listView.getListViewItemListeners().remove(this);
+        listView.getListViewItemStateListeners().remove(this);
+        listView.getListViewSelectionListeners().remove(this);
+
+        super.uninstall();
+    }
+
+    @SuppressWarnings("unchecked")
+    public int getPreferredWidth(int height) {
+        int preferredWidth = 0;
+
+        ListView listView = (ListView)getComponent();
+        List<Object> listData = (List<Object>)listView.getListData();
+
+        ListView.ItemRenderer renderer = listView.getItemRenderer();
+
+        for (Object item : listData) {
+            renderer.render(item, listView, false, false, false, false);
+            preferredWidth = Math.max(preferredWidth, renderer.getPreferredWidth(-1));
+        }
+
+        if (listView.getCheckmarksEnabled()) {
+        	preferredWidth += CHECKBOX.getWidth() + (checkboxPadding.left
+    			+ checkboxPadding.right);
+        }
+
+        return preferredWidth;
+    }
+
+    @SuppressWarnings("unchecked")
+    public int getPreferredHeight(int width) {
+        int preferredHeight = 0;
+
+        ListView listView = (ListView)getComponent();
+        List<Object> listData = (List<Object>)listView.getListData();
+        preferredHeight = listData.getLength() * getItemHeight();
+
+        return preferredHeight;
+    }
+
+    public Dimensions getPreferredSize() {
+        return new Dimensions(getPreferredWidth(-1), getPreferredHeight(-1));
+    }
+
+    public void layout() {
+        // No-op
+    }
+
+    @SuppressWarnings("unchecked")
+    public void paint(Graphics2D graphics) {
+        ListView listView = (ListView)getComponent();
+        List<Object> listData = (List<Object>)listView.getListData();
+        ListView.ItemRenderer renderer = listView.getItemRenderer();
+
+        int width = getWidth();
+        int height = getHeight();
+        int itemHeight = getItemHeight();
+
+        // Paint the background
+        graphics.setPaint(backgroundColor);
+        graphics.fillRect(0, 0, width, height);
+
+        // Paint the list contents
+        int itemStart = 0;
+        int itemEnd = listData.getLength() - 1;
+
+        // Ensure that we only paint items that are visible
+        Rectangle clipBounds = graphics.getClipBounds();
+        if (clipBounds != null) {
+            itemStart = Math.max(itemStart, (int)Math.floor(clipBounds.y
+                / (double)itemHeight));
+            itemEnd = Math.min(itemEnd, (int)Math.ceil((clipBounds.y
+                + clipBounds.height) / (double)itemHeight) - 1);
+        }
+
+        for (int itemIndex = itemStart; itemIndex <= itemEnd; itemIndex++) {
+            Object item = listData.get(itemIndex);
+            boolean highlighted = (itemIndex == highlightedIndex
+                && listView.getSelectMode() != ListView.SelectMode.NONE);
+            boolean selected = listView.isItemSelected(itemIndex);
+            boolean disabled = listView.isItemDisabled(itemIndex);
+
+            Color itemBackgroundColor = null;
+
+            if (selected) {
+                itemBackgroundColor = (listView.isFocused())
+                    ? this.selectionBackgroundColor : inactiveSelectionBackgroundColor;
+            } else {
+                if (highlighted && showHighlight && !disabled) {
+                    itemBackgroundColor = highlightBackgroundColor;
+                }
+            }
+
+            if (itemBackgroundColor != null) {
+                graphics.setPaint(itemBackgroundColor);
+                graphics.fillRect(0, itemIndex * itemHeight, width, itemHeight);
+            }
+
+            int itemX = 0;
+            int itemY = itemIndex * itemHeight;
+
+            boolean checked = false;
+            if (listView.getCheckmarksEnabled()) {
+                checked = listView.isItemChecked(itemIndex);
+
+                int checkboxY = (itemHeight - CHECKBOX.getHeight()) / 2;
+            	Graphics2D checkboxGraphics = (Graphics2D)graphics.create(checkboxPadding.left,
+        			itemY + checkboxY, CHECKBOX.getWidth(), CHECKBOX.getHeight());
+
+            	CHECKBOX.setSelected(checked);
+            	CHECKBOX.paint(checkboxGraphics);
+            	checkboxGraphics.dispose();
+
+            	itemX = CHECKBOX.getWidth() + (checkboxPadding.left
+        			+ checkboxPadding.right);
+            }
+
+            // Paint the data
+            Graphics2D rendererGraphics = (Graphics2D)graphics.create(itemX, itemY,
+                width, itemHeight);
+
+            renderer.render(item, listView, selected, checked, highlighted, disabled);
+            renderer.setSize(width, itemHeight);
+            renderer.paint(rendererGraphics);
+            rendererGraphics.dispose();
+        }
+    }
+
+    // List view skin methods
+    @SuppressWarnings("unchecked")
+    public int getItemAt(int y) {
+        if (y < 0) {
+            throw new IllegalArgumentException("y is negative");
+        }
+
+        ListView listView = (ListView)getComponent();
+
+        int index = (y / getItemHeight());
+        List<Object> listData = (List<Object>)listView.getListData();
+
+        if (index >= listData.getLength()) {
+            index = -1;
+        }
+
+        return index;
+    }
+
+    public Bounds getItemBounds(int index) {
+        int itemHeight = getItemHeight();
+        return new Bounds(0, index * itemHeight, getWidth(), itemHeight);
+    }
+
+    public int getItemIndent() {
+        int itemIndent = 0;
+
+        ListView listView = (ListView)getComponent();
+        if (listView.getCheckmarksEnabled()) {
+            itemIndent = CHECKBOX.getWidth() + checkboxPadding.left + checkboxPadding.right;
+        }
+
+        return itemIndent;
+    }
+
+    public int getItemHeight() {
+        ListView listView = (ListView)getComponent();
+        ListView.ItemRenderer renderer = listView.getItemRenderer();
+
+        int itemHeight = renderer.getPreferredHeight(-1);
+        if (listView.getCheckmarksEnabled()) {
+    		itemHeight = Math.max(CHECKBOX.getHeight() + (checkboxPadding.top
+    			+ checkboxPadding.bottom), itemHeight);
+        }
+
+		return itemHeight;
+    }
+
+    @Override
+    public boolean isFocusable() {
+        ListView listView = (ListView)getComponent();
+        return (listView.getSelectMode() != ListView.SelectMode.NONE);
+    }
+
+    public Font getFont() {
+        return font;
+    }
+
+    public void setFont(Font font) {
+        if (font == null) {
+            throw new IllegalArgumentException("font is null.");
+        }
+
+        this.font = font;
+        invalidateComponent();
+    }
+
+    public final void setFont(String font) {
+        if (font == null) {
+            throw new IllegalArgumentException("font is null.");
+        }
+
+        setFont(Font.decode(font));
+    }
+
+    public Color getColor() {
+        return color;
+    }
+
+    public void setColor(Color color) {
+        if (color == null) {
+            throw new IllegalArgumentException("color is null.");
+        }
+
+        this.color = color;
+        repaintComponent();
+    }
+
+    public final void setColor(String color) {
+        if (color == null) {
+            throw new IllegalArgumentException("color is null.");
+        }
+
+        setColor(decodeColor(color));
+    }
+
+    public Color getDisabledColor() {
+        return disabledColor;
+    }
+
+    public void setDisabledColor(Color disabledColor) {
+        if (disabledColor == null) {
+            throw new IllegalArgumentException("disabledColor is null.");
+        }
+
+        this.disabledColor = disabledColor;
+        repaintComponent();
+    }
+
+    public final void setDisabledColor(String disabledColor) {
+        if (disabledColor == null) {
+            throw new IllegalArgumentException("disabledColor is null.");
+        }
+
+        setDisabledColor(decodeColor(disabledColor));
+    }
+
+    public Color getBackgroundColor() {
+        return backgroundColor;
+    }
+
+    public void setBackgroundColor(Color backgroundColor) {
+        if (backgroundColor == null) {
+            throw new IllegalArgumentException("backgroundColor is null.");
+        }
+
+        this.backgroundColor = backgroundColor;
+        repaintComponent();
+    }
+
+    public final void setBackgroundColor(String backgroundColor) {
+        if (backgroundColor == null) {
+            throw new IllegalArgumentException("backgroundColor is null.");
+        }
+
+        setBackgroundColor(decodeColor(backgroundColor));
+    }
+
+
+    public Color getSelectionColor() {
+        return selectionColor;
+    }
+
+    public void setSelectionColor(Color selectionColor) {
+        if (selectionColor == null) {
+            throw new IllegalArgumentException("selectionColor is null.");
+        }
+
+        this.selectionColor = selectionColor;
+        repaintComponent();
+    }
+
+    public final void setSelectionColor(String selectionColor) {
+        if (selectionColor == null) {
+            throw new IllegalArgumentException("selectionColor is null.");
+        }
+
+        setSelectionColor(decodeColor(selectionColor));
+    }
+
+    public Color getSelectionBackgroundColor() {
+        return selectionBackgroundColor;
+    }
+
+    public void setSelectionBackgroundColor(Color selectionBackgroundColor) {
+        if (selectionBackgroundColor == null) {
+            throw new IllegalArgumentException("selectionBackgroundColor is null.");
+        }
+
+        this.selectionBackgroundColor = selectionBackgroundColor;
+        repaintComponent();
+    }
+
+    public final void setSelectionBackgroundColor(String selectionBackgroundColor) {
+        if (selectionBackgroundColor == null) {
+            throw new IllegalArgumentException("selectionBackgroundColor is null.");
+        }
+
+        setSelectionBackgroundColor(decodeColor(selectionBackgroundColor));
+    }
+
+    public Color getInactiveSelectionColor() {
+        return inactiveSelectionColor;
+    }
+
+    public void setInactiveSelectionColor(Color inactiveSelectionColor) {
+        if (inactiveSelectionColor == null) {
+            throw new IllegalArgumentException("inactiveSelectionColor is null.");
+        }
+
+        this.inactiveSelectionColor = inactiveSelectionColor;
+        repaintComponent();
+    }
+
+    public final void setInactiveSelectionColor(String inactiveSelectionColor) {
+        if (inactiveSelectionColor == null) {
+            throw new IllegalArgumentException("inactiveSelectionColor is null.");
+        }
+
+        setInactiveSelectionColor(decodeColor(inactiveSelectionColor));
+    }
+
+    public Color getInactiveSelectionBackgroundColor() {
+        return inactiveSelectionBackgroundColor;
+    }
+
+    public void setInactiveSelectionBackgroundColor(Color inactiveSelectionBackgroundColor) {
+        if (inactiveSelectionBackgroundColor == null) {
+            throw new IllegalArgumentException("inactiveSelectionBackgroundColor is null.");
+        }
+
+        this.inactiveSelectionBackgroundColor = inactiveSelectionBackgroundColor;
+        repaintComponent();
+    }
+
+    public final void setInactiveSelectionBackgroundColor(String inactiveSelectionBackgroundColor) {
+        if (inactiveSelectionBackgroundColor == null) {
+            throw new IllegalArgumentException("inactiveSelectionBackgroundColor is null.");
+        }
+
+        setInactiveSelectionBackgroundColor(decodeColor(inactiveSelectionBackgroundColor));
+    }
+
+    public Color getHighlightColor() {
+        return highlightColor;
+    }
+
+    public void setHighlightColor(Color highlightColor) {
+        if (highlightColor == null) {
+            throw new IllegalArgumentException("highlightColor is null.");
+        }
+
+        this.highlightColor = highlightColor;
+        repaintComponent();
+    }
+
+    public final void setHighlightColor(String highlightColor) {
+        if (highlightColor == null) {
+            throw new IllegalArgumentException("highlightColor is null.");
+        }
+
+        setHighlightColor(decodeColor(highlightColor));
+    }
+
+    public Color getHighlightBackgroundColor() {
+        return highlightBackgroundColor;
+    }
+
+    public void setHighlightBackgroundColor(Color highlightBackgroundColor) {
+        if (highlightBackgroundColor == null) {
+            throw new IllegalArgumentException("highlightBackgroundColor is null.");
+        }
+
+        this.highlightBackgroundColor = highlightBackgroundColor;
+        repaintComponent();
+    }
+
+    public final void setHighlightBackgroundColor(String highlightBackgroundColor) {
+        if (highlightBackgroundColor == null) {
+            throw new IllegalArgumentException("highlightBackgroundColor is null.");
+        }
+
+        setHighlightBackgroundColor(decodeColor(highlightBackgroundColor));
+    }
+
+    public boolean getShowHighlight() {
+        return showHighlight;
+    }
+
+    public void setShowHighlight(boolean showHighlight) {
+        this.showHighlight = showHighlight;
+        repaintComponent();
+    }
+
+    @Override
+    public boolean mouseMove(Component component, int x, int y) {
+        boolean consumed = super.mouseMove(component, x, y);
+
+        int previousHighlightedIndex = this.highlightedIndex;
+        highlightedIndex = getItemAt(y);
+
+        if (previousHighlightedIndex != highlightedIndex) {
+            if (previousHighlightedIndex != -1) {
+                repaintComponent(getItemBounds(previousHighlightedIndex));
+            }
+
+            if (highlightedIndex != -1) {
+                repaintComponent(getItemBounds(highlightedIndex));
+            }
+        }
+
+        return consumed;
+    }
+
+    @Override
+    public void mouseOut(Component component) {
+        super.mouseOut(component);
+
+        if (highlightedIndex != -1) {
+            Bounds itemBounds = getItemBounds(highlightedIndex);
+            repaintComponent(itemBounds.x, itemBounds.y, itemBounds.width, itemBounds.height);
+        }
+
+        highlightedIndex = -1;
+        editIndex = -1;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public boolean mouseDown(Component component, Mouse.Button button, int x, int y) {
+        boolean consumed = super.mouseDown(component, button, x, y);
+
+        ListView listView = (ListView)getComponent();
+        List<Object> listData = (List<Object>)listView.getListData();
+
+        int itemHeight = getItemHeight();
+        int itemIndex = y / itemHeight;
+
+        if (itemIndex < listData.getLength()
+            && !listView.isItemDisabled(itemIndex)) {
+        	int itemY = itemIndex * itemHeight;
+
+        	if (!(listView.getCheckmarksEnabled()
+        		&& x > checkboxPadding.left
+				&& x < checkboxPadding.left + CHECKBOX.getWidth()
+				&& y > itemY + checkboxPadding.top
+				&& y < itemY + checkboxPadding.top + CHECKBOX.getHeight())) {
+                ListView.SelectMode selectMode = listView.getSelectMode();
+                if (Keyboard.isPressed(Keyboard.Modifier.SHIFT)
+                    && selectMode == ListView.SelectMode.MULTI) {
+                    // Select the range
+                    int startIndex = listView.getFirstSelectedIndex();
+                    int endIndex = listView.getLastSelectedIndex();
+                    Span selectedRange = (itemIndex > startIndex) ?
+                        new Span(startIndex, itemIndex) : new Span(itemIndex, endIndex);
+
+                    ArrayList<Span> selectedRanges = new ArrayList<Span>();
+                    Sequence<Integer> disabledIndexes = listView.getDisabledIndexes();
+                    if (disabledIndexes.getLength() == 0) {
+                        selectedRanges.add(selectedRange);
+                    } else {
+                        // TODO Split the range by the disabled indexes; for now,
+                        // just return
+                        return consumed;
+                    }
+
+                    listView.setSelectedRanges(selectedRanges);
+                } else if (Keyboard.isPressed(Keyboard.Modifier.CTRL)
+                    && selectMode == ListView.SelectMode.MULTI) {
+                    // Toggle the item's selection state
+                    if (listView.isItemSelected(itemIndex)) {
+                        listView.removeSelectedIndex(itemIndex);
+                    } else {
+                        listView.addSelectedIndex(itemIndex);
+                    }
+                } else {
+                    if (selectMode != ListView.SelectMode.NONE) {
+                        if (listView.isItemSelected(itemIndex)
+                            && listView.isFocused()) {
+                            // Edit the item
+                            editIndex = itemIndex;
+                        } else {
+                            // Select the item
+                            listView.setSelectedIndex(itemIndex);
+                        }
+                    }
+                }
+        	}
+        }
+
+        listView.requestFocus();
+
+        return consumed;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public boolean mouseClick(Component component, Mouse.Button button, int x, int y, int count) {
+        boolean consumed = super.mouseClick(component, button, x, y, count);
+
+        ListView listView = (ListView)getComponent();
+
+        List<Object> listData = (List<Object>)listView.getListData();
+
+        int itemHeight = getItemHeight();
+        int itemIndex = y / itemHeight;
+
+        if (itemIndex < listData.getLength()
+            && !listView.isItemDisabled(itemIndex)) {
+            int itemY = itemIndex * itemHeight;
+
+            if (listView.getCheckmarksEnabled()
+                && x > checkboxPadding.left
+                && x < checkboxPadding.left + CHECKBOX.getWidth()
+                && y > itemY + checkboxPadding.top
+                && y < itemY + checkboxPadding.top + CHECKBOX.getHeight()) {
+                listView.setItemChecked(itemIndex, !listView.isItemChecked(itemIndex));
+            } else {
+                if (editIndex != -1
+                    && count == 1) {
+                    ListView.ItemEditor itemEditor = listView.getItemEditor();
+
+                    if (itemEditor != null) {
+                        itemEditor.edit(listView, editIndex);
+                    }
+                }
+
+                editIndex = -1;
+            }
+        }
+
+        return consumed;
+    }
+
+    @Override
+    public boolean mouseWheel(Component component, Mouse.ScrollType scrollType, int scrollAmount,
+        int wheelRotation, int x, int y) {
+        if (highlightedIndex != -1) {
+            Bounds itemBounds = getItemBounds(highlightedIndex);
+            repaintComponent(itemBounds.x, itemBounds.y, itemBounds.width, itemBounds.height);
+        }
+
+        highlightedIndex = -1;
+
+        return super.mouseWheel(component, scrollType, scrollAmount, wheelRotation, x, y);
+    }
+
+    @Override
+    public boolean keyPressed(Component component, int keyCode, Keyboard.KeyLocation keyLocation) {
+        boolean consumed = super.keyPressed(component, keyCode, keyLocation);
+
+        ListView listView = (ListView)getComponent();
+
+        switch (keyCode) {
+            case Keyboard.KeyCode.UP: {
+                int index = listView.getFirstSelectedIndex();
+
+                do {
+                    index--;
+                } while (index >= 0
+                    && listView.isItemDisabled(index));
+
+                if (index >= 0) {
+                    if (Keyboard.isPressed(Keyboard.Modifier.SHIFT)
+                        && listView.getSelectMode() == ListView.SelectMode.MULTI) {
+                        listView.addSelectedIndex(index);
+                    } else {
+                        listView.setSelectedIndex(index);
+                    }
+
+                    listView.scrollAreaToVisible(getItemBounds(index));
+                }
+
+                consumed = true;
+                break;
+            }
+
+            case Keyboard.KeyCode.DOWN: {
+                int index = listView.getLastSelectedIndex();
+                int count = listView.getListData().getLength();
+
+                do {
+                    index++;
+                } while (index < count
+                    && listView.isItemDisabled(index));
+
+                if (index < count) {
+                    if (Keyboard.isPressed(Keyboard.Modifier.SHIFT)
+                        && listView.getSelectMode() == ListView.SelectMode.MULTI) {
+                        listView.addSelectedIndex(index);
+                    } else {
+                        listView.setSelectedIndex(index);
+                    }
+
+                    listView.scrollAreaToVisible(getItemBounds(index));
+                }
+
+                consumed = true;
+                break;
+            }
+        }
+
+        // Clear the highlight
+        if (highlightedIndex != -1) {
+            highlightedIndex = -1;
+            repaintComponent(getItemBounds(highlightedIndex));
+        }
+
+        return consumed;
+    }
+
+    @Override
+    public boolean keyReleased(Component component, int keyCode, Keyboard.KeyLocation keyLocation) {
+        boolean consumed = super.keyReleased(component, keyCode, keyLocation);
+
+        ListView listView = (ListView)getComponent();
+
+        switch (keyCode) {
+            case Keyboard.KeyCode.SPACE: {
+                if (listView.getCheckmarksEnabled()
+                    && listView.getSelectMode() == ListView.SelectMode.SINGLE) {
+                    int selectedIndex = listView.getSelectedIndex();
+                    listView.setItemChecked(selectedIndex, !listView.isItemChecked(selectedIndex));
+                    consumed = true;
+                }
+
+                break;
+            }
+        }
+
+        return consumed;
+    }
+
+    // Component state events
+    @Override
+    public void enabledChanged(Component component) {
+        super.enabledChanged(component);
+
+        repaintComponent();
+    }
+
+    @Override
+    public void focusedChanged(Component component, boolean temporary) {
+        super.focusedChanged(component, temporary);
+
+        repaintComponent();
+    }
+
+    // List view events
+    public void listDataChanged(ListView listView, List<?> previousListData) {
+        invalidateComponent();
+    }
+
+    public void itemRendererChanged(ListView listView, ListView.ItemRenderer previousItemRenderer) {
+        invalidateComponent();
+    }
+
+    public void itemEditorChanged(ListView listView, ListView.ItemEditor previousItemEditor) {
+        // No-op
+    }
+
+    public void selectModeChanged(ListView listView, ListView.SelectMode previousSelectMode) {
+        repaintComponent();
+    }
+
+    public void checkmarksEnabledChanged(ListView listView) {
+    	invalidateComponent();
+    }
+
+    public void selectedItemKeyChanged(ListView listView, String previousSelectedItemKey) {
+        // No-op
+    }
+
+    public void selectedItemsKeyChanged(ListView listView, String previousSelectedItemsKey) {
+        // No-op
+    }
+
+    // List view item events
+    public void itemInserted(ListView listView, int index) {
+        invalidateComponent();
+    }
+
+    public void itemsRemoved(ListView listView, int index, int count) {
+        invalidateComponent();
+    }
+
+    public void itemUpdated(ListView listView, int index) {
+        invalidateComponent();
+    }
+
+    public void itemsSorted(ListView listView) {
+        repaintComponent();
+    }
+
+    // List view item state events
+    public void itemDisabledChanged(ListView listView, int index) {
+        repaintComponent(getItemBounds(index));
+    }
+
+    public void itemCheckedChanged(ListView listView, int index) {
+        repaintComponent(getItemBounds(index));
+    }
+
+    // List view selection detail events
+    public void selectedRangeAdded(ListView listView, int rangeStart, int rangeEnd) {
+        // Repaint the area containing the added selection
+        int itemHeight = getItemHeight();
+        repaintComponent(0, rangeStart * itemHeight,
+            getWidth(), (rangeEnd - rangeStart + 1) * itemHeight);
+    }
+
+    public void selectedRangeRemoved(ListView listView, int rangeStart, int rangeEnd) {
+        // Repaint the area containing the removed selection
+        int itemHeight = getItemHeight();
+        repaintComponent(0, rangeStart * itemHeight,
+            getWidth(), (rangeEnd - rangeStart + 1) * itemHeight);
+    }
+
+    public void selectedRangesChanged(ListView listView, Sequence<Span> previousSelectedRanges) {
+        // TODO Repaint only the area that changed (intersection of previous
+        // and new selection)
+        repaintComponent();
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuBarItemSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuBarItemSkin.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuBarItemSkin.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuBarItemSkin.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.skin.terra;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+
+import pivot.wtk.Button;
+import pivot.wtk.Component;
+import pivot.wtk.Cursor;
+import pivot.wtk.Dimensions;
+import pivot.wtk.MenuBar;
+import pivot.wtk.skin.MenuBarItemSkin;
+
+/**
+ * Terra menu bar item skin.
+ *
+ * @author gbrown
+ */
+public class TerraMenuBarItemSkin extends MenuBarItemSkin {
+    @Override
+    public void install(Component component) {
+        super.install(component);
+
+        MenuBar.Item menuBarItem = (MenuBar.Item)component;
+        menuBarItem.setCursor(Cursor.DEFAULT);
+    }
+
+    public int getPreferredWidth(int height) {
+        MenuBar.Item menuBarItem = (MenuBar.Item)getComponent();
+
+        Button.DataRenderer dataRenderer = menuBarItem.getDataRenderer();
+        dataRenderer.render(menuBarItem.getButtonData(), menuBarItem, false);
+
+        return dataRenderer.getPreferredWidth(height);
+    }
+
+    public int getPreferredHeight(int width) {
+        MenuBar.Item menuBarItem = (MenuBar.Item)getComponent();
+
+        Button.DataRenderer dataRenderer = menuBarItem.getDataRenderer();
+        dataRenderer.render(menuBarItem.getButtonData(), menuBarItem, false);
+
+        return dataRenderer.getPreferredHeight(width);
+    }
+
+    public Dimensions getPreferredSize() {
+        MenuBar.Item menuBarItem = (MenuBar.Item)getComponent();
+
+        Button.DataRenderer dataRenderer = menuBarItem.getDataRenderer();
+        dataRenderer.render(menuBarItem.getButtonData(), menuBarItem, false);
+
+        return dataRenderer.getPreferredSize();
+    }
+
+    public void layout() {
+        // No-op
+    }
+
+    public void paint(Graphics2D graphics) {
+        MenuBar.Item menuBarItem = (MenuBar.Item)getComponent();
+        MenuBar menuBar = menuBarItem.getMenuBar();
+
+        int width = getWidth();
+        int height = getHeight();
+
+        boolean highlight = menuPopup.isOpen();
+
+        // Paint highlight state
+        if (highlight) {
+            Color highlightBackgroundColor = (Color)menuBar.getStyles().get("highlightBackgroundColor");
+            graphics.setColor(highlightBackgroundColor);
+            graphics.fillRect(0, 0, width, height);
+        }
+
+        // Paint the content
+        Button.DataRenderer dataRenderer = menuBarItem.getDataRenderer();
+        dataRenderer.render(menuBarItem.getButtonData(), menuBarItem, highlight);
+        dataRenderer.setSize(width, height);
+
+        dataRenderer.paint(graphics);
+    }
+
+    public Color getPopupBorderColor() {
+        return (Color)menuPopup.getStyles().get("borderColor");
+    }
+
+    public void setPopupBorderColor(Color popupBorderColor) {
+        menuPopup.getStyles().put("borderColor", popupBorderColor);
+    }
+
+    public void setPopupBorderColor(String popupBorderColor) {
+        if (popupBorderColor == null) {
+            throw new IllegalArgumentException("popupBorderColor is null.");
+        }
+
+        menuPopup.getStyles().put("borderColor", popupBorderColor);
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuBarSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuBarSkin.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuBarSkin.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuBarSkin.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.skin.terra;
+
+import java.awt.Color;
+import java.awt.Font;
+
+import pivot.collections.Sequence;
+import pivot.wtk.Component;
+import pivot.wtk.Dimensions;
+import pivot.wtk.MenuBar;
+import pivot.wtk.MenuBarListener;
+import pivot.wtk.Theme;
+import pivot.wtk.skin.ContainerSkin;
+
+/**
+ * Menu bar skin.
+ *
+ * @author gbrown
+ */
+public class TerraMenuBarSkin extends ContainerSkin implements MenuBarListener {
+    private Font font;
+    private Color color;
+    private Color disabledColor;
+    private Color highlightColor;
+    private Color highlightBackgroundColor;
+    private int spacing;
+
+    public TerraMenuBarSkin() {
+        TerraTheme theme = (TerraTheme)Theme.getTheme();
+        setBackgroundColor(theme.getColor(4));
+
+        font = theme.getFont().deriveFont(Font.BOLD);
+        color = theme.getColor(1);
+        disabledColor = theme.getColor(7);
+        highlightColor = theme.getColor(4);
+        highlightBackgroundColor = theme.getColor(20);
+        spacing = 2;
+    }
+
+    public void install(Component component) {
+        super.install(component);
+
+        MenuBar menuBar = (MenuBar)component;
+        menuBar.getMenuBarListeners().add(this);
+
+        menuBar.setFocusTraversalPolicy(new IndexFocusTraversalPolicy(true));
+    }
+
+    public void uninstall() {
+        MenuBar menuBar = (MenuBar)getComponent();
+        menuBar.getMenuBarListeners().remove(this);
+
+        menuBar.setFocusTraversalPolicy(null);
+
+        super.uninstall();
+    }
+
+    public int getPreferredWidth(int height) {
+        int preferredWidth = 0;
+
+        MenuBar menuBar = (MenuBar)getComponent();
+        MenuBar.ItemSequence items = menuBar.getItems();
+
+        int j = 0;
+        for (int i = 0, n = items.getLength(); i < n; i++) {
+            if (j > 0) {
+                preferredWidth += spacing;
+            }
+
+            MenuBar.Item item = items.get(i);
+            if (item.isDisplayable()) {
+                preferredWidth += item.getPreferredWidth(height);
+                j++;
+            }
+        }
+
+        return preferredWidth;
+    }
+
+    public int getPreferredHeight(int width) {
+        int preferredHeight = 0;
+
+        MenuBar menuBar = (MenuBar)getComponent();
+        MenuBar.ItemSequence items = menuBar.getItems();
+
+        for (int i = 0, n = items.getLength(); i < n; i++) {
+            MenuBar.Item item = items.get(i);
+            if (item.isDisplayable()) {
+                preferredHeight = Math.max(item.getPreferredHeight(width), preferredHeight);
+            }
+        }
+
+        return preferredHeight;
+    }
+
+    public Dimensions getPreferredSize() {
+        int preferredWidth = 0;
+        int preferredHeight = 0;
+
+        MenuBar menuBar = (MenuBar)getComponent();
+        MenuBar.ItemSequence items = menuBar.getItems();
+
+        int j = 0;
+        for (int i = 0, n = items.getLength(); i < n; i++) {
+            if (j > 0) {
+                preferredWidth += spacing;
+            }
+
+            MenuBar.Item item = items.get(i);
+            if (item.isDisplayable()) {
+                preferredWidth += item.getPreferredWidth(-1);
+                preferredHeight = Math.max(item.getPreferredHeight(-1), preferredHeight);
+            }
+        }
+
+        return new Dimensions(preferredWidth, preferredHeight);
+    }
+
+    public void layout() {
+        MenuBar menuBar = (MenuBar)getComponent();
+
+        int height = getHeight();
+        int itemX = 0;
+
+        for (MenuBar.Item item : menuBar.getItems()) {
+            if (item.isDisplayable()) {
+                item.setVisible(true);
+                item.setSize(item.getPreferredWidth(height), height);
+                item.setLocation(itemX, 0);
+
+                itemX += item.getWidth() + spacing;
+            } else {
+                item.setVisible(false);
+            }
+        }
+    }
+
+    public final void setBackgroundColor(int color) {
+        TerraTheme theme = (TerraTheme)Theme.getTheme();
+        setBackgroundColor(theme.getColor(color));
+    }
+
+    public Font getFont() {
+        return font;
+    }
+
+    public void setFont(Font font) {
+        if (font == null) {
+            throw new IllegalArgumentException("font is null.");
+        }
+
+        this.font = font;
+        invalidateComponent();
+    }
+
+    public final void setFont(String font) {
+        if (font == null) {
+            throw new IllegalArgumentException("font is null.");
+        }
+
+        setFont(Font.decode(font));
+    }
+
+    public Color getColor() {
+        return color;
+    }
+
+    public void setColor(Color color) {
+        if (color == null) {
+            throw new IllegalArgumentException("color is null.");
+        }
+
+        this.color = color;
+        repaintComponent();
+    }
+
+    public final void setColor(String color) {
+        if (color == null) {
+            throw new IllegalArgumentException("color is null.");
+        }
+
+        setColor(decodeColor(color));
+    }
+
+    public final void setColor(int color) {
+        TerraTheme theme = (TerraTheme)Theme.getTheme();
+        setColor(theme.getColor(color));
+    }
+
+    public Color getDisabledColor() {
+        return disabledColor;
+    }
+
+    public void setDisabledColor(Color disabledColor) {
+        if (disabledColor == null) {
+            throw new IllegalArgumentException("disabledColor is null.");
+        }
+
+        this.disabledColor = disabledColor;
+        repaintComponent();
+    }
+
+    public final void setDisabledColor(String disabledColor) {
+        if (disabledColor == null) {
+            throw new IllegalArgumentException("disabledColor is null.");
+        }
+
+        setDisabledColor(decodeColor(disabledColor));
+    }
+
+    public final void setDisabledColor(int color) {
+        TerraTheme theme = (TerraTheme)Theme.getTheme();
+        setDisabledColor(theme.getColor(color));
+    }
+
+    public Color getHighlightColor() {
+        return highlightColor;
+    }
+
+    public void setHighlightColor(Color highlightColor) {
+        if (highlightColor == null) {
+            throw new IllegalArgumentException("highlightColor is null.");
+        }
+
+        this.highlightColor = highlightColor;
+        repaintComponent();
+    }
+
+    public final void setHighlightColor(String highlightColor) {
+        if (highlightColor == null) {
+            throw new IllegalArgumentException("highlightColor is null.");
+        }
+
+        setHighlightColor(decodeColor(highlightColor));
+    }
+
+    public final void setHighlightColor(int color) {
+        TerraTheme theme = (TerraTheme)Theme.getTheme();
+        setHighlightColor(theme.getColor(color));
+    }
+
+    public Color getHighlightBackgroundColor() {
+        return highlightBackgroundColor;
+    }
+
+    public void setHighlightBackgroundColor(Color highlightBackgroundColor) {
+        if (highlightBackgroundColor == null) {
+            throw new IllegalArgumentException("highlightBackgroundColor is null.");
+        }
+
+        this.highlightBackgroundColor = highlightBackgroundColor;
+        repaintComponent();
+    }
+
+    public final void setHighlightBackgroundColor(String highlightBackgroundColor) {
+        if (highlightBackgroundColor == null) {
+            throw new IllegalArgumentException("highlightBackgroundColor is null.");
+        }
+
+        setHighlightBackgroundColor(decodeColor(highlightBackgroundColor));
+    }
+
+    public final void setHighlightBackgroundColor(int color) {
+        TerraTheme theme = (TerraTheme)Theme.getTheme();
+        setHighlightBackgroundColor(theme.getColor(color));
+    }
+
+    public int getSpacing() {
+        return spacing;
+    }
+
+    public void setSpacing(int spacing) {
+        if (spacing < 0) {
+            throw new IllegalArgumentException("Spacing is negative.");
+        }
+
+        this.spacing = spacing;
+        invalidateComponent();
+    }
+
+    public void itemInserted(MenuBar menuBar, int index) {
+        invalidateComponent();
+    }
+
+    public void itemsRemoved(MenuBar menuBar, int index, Sequence<MenuBar.Item> removed) {
+        invalidateComponent();
+    }
+
+    public void activeChanged(MenuBar menuBar) {
+        // No-op
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuButtonSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuButtonSkin.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuButtonSkin.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuButtonSkin.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.skin.terra;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.GradientPaint;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.GeneralPath;
+
+import pivot.collections.Dictionary;
+import pivot.wtk.Bounds;
+import pivot.wtk.Button;
+import pivot.wtk.Component;
+import pivot.wtk.Dimensions;
+import pivot.wtk.Insets;
+import pivot.wtk.MenuButton;
+import pivot.wtk.Theme;
+import pivot.wtk.skin.MenuButtonSkin;
+
+/**
+ * Terra menu button skin.
+ *
+ * @author gbrown
+ */
+public class TerraMenuButtonSkin extends MenuButtonSkin {
+    private Font font;
+    private Color color;
+    private Color disabledColor;
+    private Color backgroundColor;
+    private Color disabledBackgroundColor;
+    private Color borderColor;
+    private Color disabledBorderColor;
+    private Insets padding;
+    private int spacing;
+    private boolean toolbar;
+
+    // Derived colors
+    private Color bevelColor;
+    private Color pressedBevelColor;
+    private Color disabledBevelColor;
+
+    private static final int TRIGGER_WIDTH = 10;
+
+    public TerraMenuButtonSkin() {
+        TerraTheme theme = (TerraTheme)Theme.getTheme();
+
+        font = theme.getFont();
+        color = theme.getColor(1);
+        disabledColor = theme.getColor(7);
+        backgroundColor = theme.getColor(10);
+        disabledBackgroundColor = theme.getColor(10);
+        borderColor = theme.getColor(7);
+        disabledBorderColor = theme.getColor(7);
+        padding = new Insets(3);
+        spacing = 0;
+        toolbar = false;
+
+        // Set the derived colors
+        bevelColor = TerraTheme.brighten(backgroundColor);
+        pressedBevelColor = TerraTheme.darken(backgroundColor);
+        disabledBevelColor = disabledBackgroundColor;
+    }
+
+    public int getPreferredWidth(int height) {
+        MenuButton menuButton = (MenuButton)getComponent();
+        Button.DataRenderer dataRenderer = menuButton.getDataRenderer();
+
+        if (height != -1) {
+            height = Math.max(height - (padding.top + padding.bottom + 2), 0);
+        }
+
+        dataRenderer.render(menuButton.getButtonData(), menuButton, false);
+
+        int preferredWidth = dataRenderer.getPreferredWidth(-1) + TRIGGER_WIDTH
+            + padding.left + padding.right + spacing + 2;
+
+        return preferredWidth;
+    }
+
+    public int getPreferredHeight(int width) {
+        MenuButton menuButton = (MenuButton)getComponent();
+        Button.DataRenderer dataRenderer = menuButton.getDataRenderer();
+
+        dataRenderer.render(menuButton.getButtonData(), menuButton, false);
+
+        int preferredHeight = dataRenderer.getPreferredHeight(-1)
+            + padding.top + padding.bottom + 2;
+
+        return preferredHeight;
+    }
+
+    public Dimensions getPreferredSize() {
+        // TODO Optimize by performing calcuations locally
+        return new Dimensions(getPreferredWidth(-1), getPreferredHeight(-1));
+    }
+
+    public void layout() {
+        // No-op
+    }
+
+    public void paint(Graphics2D graphics) {
+        MenuButton menuButton = (MenuButton)getComponent();
+
+        int width = getWidth();
+        int height = getHeight();
+
+        Color backgroundColor = null;
+        Color bevelColor = null;
+        Color borderColor = null;
+
+        if (!toolbar
+            || highlighted
+            || menuPopup.isOpen()) {
+            if (menuButton.isEnabled()) {
+                backgroundColor = this.backgroundColor;
+                bevelColor = (pressed || menuPopup.isOpen()) ? pressedBevelColor : this.bevelColor;
+                borderColor = this.borderColor;
+            } else {
+                backgroundColor = disabledBackgroundColor;
+                bevelColor = disabledBevelColor;
+                borderColor = disabledBorderColor;
+            }
+        }
+
+        graphics.setStroke(new BasicStroke());
+
+        // Paint the background
+    	if (backgroundColor != null
+			&& bevelColor != null) {
+            graphics.setPaint(new GradientPaint(width / 2, 0, bevelColor,
+                width / 2, height / 2, backgroundColor));
+            graphics.fillRect(0, 0, width, height);
+    	}
+
+        // Paint the border
+        if (borderColor != null) {
+            graphics.setPaint(borderColor);
+            graphics.drawRect(0, 0, width - 1, height - 1);
+        }
+
+        Bounds contentBounds = new Bounds(padding.left + 1, padding.top + 1,
+            Math.max(width - (padding.left + padding.right + spacing + TRIGGER_WIDTH + 2), 0),
+            Math.max(height - (padding.top + padding.bottom + 2), 0));
+
+        // Paint the content
+        Button.DataRenderer dataRenderer = menuButton.getDataRenderer();
+        dataRenderer.render(menuButton.getButtonData(), menuButton, highlighted);
+        dataRenderer.setSize(contentBounds.width, contentBounds.height);
+
+        Graphics2D contentGraphics = (Graphics2D)graphics.create();
+        contentGraphics.translate(contentBounds.x, contentBounds.y);
+        contentGraphics.clipRect(0, 0, contentBounds.width, contentBounds.height);
+        dataRenderer.paint(contentGraphics);
+        contentGraphics.dispose();
+
+        // Paint the trigger
+        Bounds triggerBounds = new Bounds(Math.max(width - (padding.right + TRIGGER_WIDTH), 0),
+            0, TRIGGER_WIDTH, Math.max(height - (padding.top - padding.bottom), 0));
+
+        GeneralPath triggerIconShape = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
+        triggerIconShape.moveTo(0, 0);
+        triggerIconShape.lineTo(3, 3);
+        triggerIconShape.lineTo(6, 0);
+        triggerIconShape.closePath();
+
+        Graphics2D triggerGraphics = (Graphics2D)graphics.create();
+        triggerGraphics.setStroke(new BasicStroke(0));
+        triggerGraphics.setPaint(color);
+
+        int tx = triggerBounds.x + Math.round((triggerBounds.width - triggerIconShape.getBounds().width) / 2);
+        int ty = triggerBounds.y + Math.round((triggerBounds.height - triggerIconShape.getBounds().height) / 2f);
+        triggerGraphics.translate(tx, ty);
+
+        triggerGraphics.draw(triggerIconShape);
+        triggerGraphics.fill(triggerIconShape);
+
+        triggerGraphics.dispose();
+
+        // Paint the focus state
+        if (menuButton.isFocused()) {
+            BasicStroke dashStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND,
+                BasicStroke.JOIN_ROUND, 1.0f, new float[] {0.0f, 2.0f}, 0.0f);
+
+            graphics.setStroke(dashStroke);
+            graphics.setColor(borderColor);
+
+            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                RenderingHints.VALUE_ANTIALIAS_ON);
+
+            graphics.drawRect(2, 2, Math.max(width - 5, 0),
+                Math.max(height - 5, 0));
+
+            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                RenderingHints.VALUE_ANTIALIAS_OFF);
+        }
+    }
+
+    @Override
+    public boolean isFocusable() {
+        return !toolbar;
+    }
+
+    public Font getFont() {
+        return font;
+    }
+
+    public void setFont(Font font) {
+        if (font == null) {
+            throw new IllegalArgumentException("font is null.");
+        }
+
+        this.font = font;
+        invalidateComponent();
+    }
+
+    public final void setFont(String font) {
+        if (font == null) {
+            throw new IllegalArgumentException("font is null.");
+        }
+
+        setFont(Font.decode(font));
+    }
+
+    public Color getColor() {
+        return color;
+    }
+
+    public void setColor(Color color) {
+        if (color == null) {
+            throw new IllegalArgumentException("color is null.");
+        }
+
+        this.color = color;
+        repaintComponent();
+    }
+
+    public final void setColor(String color) {
+        if (color == null) {
+            throw new IllegalArgumentException("color is null.");
+        }
+
+        setColor(decodeColor(color));
+    }
+
+    public Color getDisabledColor() {
+        return disabledColor;
+    }
+
+    public void setDisabledColor(Color disabledColor) {
+        if (disabledColor == null) {
+            throw new IllegalArgumentException("disabledColor is null.");
+        }
+
+        this.disabledColor = disabledColor;
+        repaintComponent();
+    }
+
+    public final void setDisabledColor(String disabledColor) {
+        if (disabledColor == null) {
+            throw new IllegalArgumentException("disabledColor is null.");
+        }
+
+        setDisabledColor(decodeColor(disabledColor));
+    }
+
+    public Color getBackgroundColor() {
+        return backgroundColor;
+    }
+
+    public void setBackgroundColor(Color backgroundColor) {
+        if (backgroundColor == null) {
+            throw new IllegalArgumentException("backgroundColor is null.");
+        }
+
+        this.backgroundColor = backgroundColor;
+        bevelColor = TerraTheme.brighten(backgroundColor);
+        pressedBevelColor = TerraTheme.darken(backgroundColor);
+        repaintComponent();
+    }
+
+    public final void setBackgroundColor(String backgroundColor) {
+        if (backgroundColor == null) {
+            throw new IllegalArgumentException("backgroundColor is null.");
+        }
+
+        setBackgroundColor(decodeColor(backgroundColor));
+    }
+
+    public Color getDisabledBackgroundColor() {
+        return disabledBackgroundColor;
+    }
+
+    public void setDisabledBackgroundColor(Color disabledBackgroundColor) {
+        if (disabledBackgroundColor == null) {
+            throw new IllegalArgumentException("disabledBackgroundColor is null.");
+        }
+
+        this.disabledBackgroundColor = disabledBackgroundColor;
+        disabledBevelColor = disabledBackgroundColor;
+        repaintComponent();
+    }
+
+    public final void setDisabledBackgroundColor(String disabledBackgroundColor) {
+        if (disabledBackgroundColor == null) {
+            throw new IllegalArgumentException("disabledBackgroundColor is null.");
+        }
+
+        setDisabledBackgroundColor(decodeColor(disabledBackgroundColor));
+    }
+
+    public Color getBorderColor() {
+        return borderColor;
+    }
+
+    public void setBorderColor(Color borderColor) {
+        if (borderColor == null) {
+            throw new IllegalArgumentException("borderColor is null.");
+        }
+
+        this.borderColor = borderColor;
+        menuPopup.getStyles().put("borderColor", borderColor);
+        repaintComponent();
+    }
+
+    public final void setBorderColor(String borderColor) {
+        if (borderColor == null) {
+            throw new IllegalArgumentException("borderColor is null.");
+        }
+
+        setBorderColor(decodeColor(borderColor));
+    }
+
+    public Color getDisabledBorderColor() {
+        return disabledBorderColor;
+    }
+
+    public void setDisabledBorderColor(Color disabledBorderColor) {
+        if (disabledBorderColor == null) {
+            throw new IllegalArgumentException("disabledBorderColor is null.");
+        }
+
+        this.disabledBorderColor = disabledBorderColor;
+        repaintComponent();
+    }
+
+    public final void setDisabledBorderColor(String disabledBorderColor) {
+        if (disabledBorderColor == null) {
+            throw new IllegalArgumentException("disabledBorderColor is null.");
+        }
+
+        setDisabledBorderColor(decodeColor(disabledBorderColor));
+    }
+
+    public Insets getPadding() {
+        return padding;
+    }
+
+    public void setPadding(Insets padding) {
+        if (padding == null) {
+            throw new IllegalArgumentException("padding is null.");
+        }
+
+        this.padding = padding;
+        invalidateComponent();
+    }
+
+    public final void setPadding(Dictionary<String, ?> padding) {
+        if (padding == null) {
+            throw new IllegalArgumentException("padding is null.");
+        }
+
+        setPadding(new Insets(padding));
+    }
+
+    public final void setPadding(int padding) {
+        setPadding(new Insets(padding));
+    }
+
+    public final void setPadding(Number padding) {
+        if (padding == null) {
+            throw new IllegalArgumentException("padding is null.");
+        }
+
+        setPadding(padding.intValue());
+    }
+
+    public int getSpacing() {
+        return spacing;
+    }
+
+    public void setSpacing(int spacing) {
+        this.spacing = spacing;
+        invalidateComponent();
+    }
+
+    public final void setSpacing(Number spacing) {
+        if (spacing == null) {
+            throw new IllegalArgumentException("spacing is null.");
+        }
+
+        setSpacing(spacing.intValue());
+    }
+
+    public boolean isToolbar() {
+        return toolbar;
+    }
+
+    public void setToolbar(boolean toolbar) {
+        this.toolbar = toolbar;
+
+        if (toolbar &&
+            getComponent().isFocused()) {
+            Component.clearFocus();
+        }
+
+        repaintComponent();
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuItemSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuItemSkin.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuItemSkin.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/skin/terra/TerraMenuItemSkin.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.skin.terra;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.GradientPaint;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+
+import pivot.wtk.Button;
+import pivot.wtk.Component;
+import pivot.wtk.Cursor;
+import pivot.wtk.Dimensions;
+import pivot.wtk.Menu;
+import pivot.wtk.media.Image;
+import pivot.wtk.skin.MenuItemSkin;
+
+/**
+ * Terra menu item skin.
+ *
+ * @author gbrown
+ */
+public class TerraMenuItemSkin extends MenuItemSkin {
+    public final class CheckmarkImage extends Image {
+        public static final int SIZE = 14;
+        public static final int CHECKMARK_SIZE = 10;
+
+        public int getWidth() {
+            return SIZE;
+        }
+
+        public int getHeight() {
+            return SIZE;
+        }
+
+        public void paint(Graphics2D graphics) {
+            Menu.Item menuItem = (Menu.Item)getComponent();
+            Menu menu = menuItem.getSection().getMenu();
+
+            Color color = (Color)menu.getStyles().get("color");
+            graphics.setColor(color);
+            graphics.setStroke(new BasicStroke(2.5f));
+
+            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                RenderingHints.VALUE_ANTIALIAS_ON);
+
+            // Draw a checkmark
+            int n = CHECKMARK_SIZE / 2;
+            int m = CHECKMARK_SIZE / 4;
+            int offsetX = (SIZE - (n + m)) / 2;
+            int offsetY = (SIZE - n) / 2;
+
+            graphics.drawLine(offsetX, (n - m) + offsetY,
+                m + offsetX, n + offsetY);
+            graphics.drawLine(m + offsetX, n + offsetY,
+                (m + n) + offsetX, offsetY);
+        }
+    }
+
+    private Image checkmarkImage = new CheckmarkImage();
+
+    public static final int EXPANDER_SIZE = 11;
+    public static final int EXPANDER_ICON_SIZE = 5;
+
+    @Override
+    public void install(Component component) {
+        super.install(component);
+
+        Menu.Item menuItem = (Menu.Item)component;
+        menuItem.setCursor(Cursor.DEFAULT);
+    }
+
+    public int getPreferredWidth(int height) {
+        Menu.Item menuItem = (Menu.Item)getComponent();
+
+        Button.DataRenderer dataRenderer = menuItem.getDataRenderer();
+        dataRenderer.render(menuItem.getButtonData(), menuItem, false);
+
+        return dataRenderer.getPreferredWidth(height) + EXPANDER_SIZE;
+    }
+
+    public int getPreferredHeight(int width) {
+        Menu.Item menuItem = (Menu.Item)getComponent();
+
+        Button.DataRenderer dataRenderer = menuItem.getDataRenderer();
+        dataRenderer.render(menuItem.getButtonData(), menuItem, false);
+
+        return Math.max(dataRenderer.getPreferredHeight(width), EXPANDER_SIZE);
+    }
+
+    public Dimensions getPreferredSize() {
+        Menu.Item menuItem = (Menu.Item)getComponent();
+
+        Button.DataRenderer dataRenderer = menuItem.getDataRenderer();
+        dataRenderer.render(menuItem.getButtonData(), menuItem, false);
+
+        Dimensions preferredSize = dataRenderer.getPreferredSize();
+
+        preferredSize.width += EXPANDER_SIZE;
+        preferredSize.height = Math.max(preferredSize.height, EXPANDER_SIZE);
+
+        return preferredSize;
+    }
+
+    public void layout() {
+        // No-op
+    }
+
+    public void paint(Graphics2D graphics) {
+        Menu.Item menuItem = (Menu.Item)getComponent();
+        Menu menu = menuItem.getSection().getMenu();
+
+        int width = getWidth();
+        int height = getHeight();
+
+        boolean highlight = (menuItem.isFocused()
+            || menuPopup.isOpen());
+
+        // Paint highlight state
+        if (highlight) {
+            Color highlightBackgroundColor = (Color)menu.getStyles().get("highlightBackgroundColor");
+            graphics.setPaint(new GradientPaint(width / 2, 0, TerraTheme.brighten(highlightBackgroundColor),
+                width / 2, height, highlightBackgroundColor));
+            graphics.fillRect(0, 0, width, height);
+        }
+
+        // Paint the content
+        Button.DataRenderer dataRenderer = menuItem.getDataRenderer();
+        dataRenderer.render(menuItem.getButtonData(), menuItem, highlight);
+        dataRenderer.setSize(Math.max(width - EXPANDER_SIZE, 0), height);
+
+        dataRenderer.paint(graphics);
+
+        // Paint the expander
+        if (menuItem.getMenu() != null) {
+            Color color = (Color)(highlight ?
+                menu.getStyles().get("highlightColor") : menu.getStyles().get("color"));
+            graphics.setColor(color);
+            graphics.setStroke(new BasicStroke(0));
+
+            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                RenderingHints.VALUE_ANTIALIAS_ON);
+
+            graphics.translate(dataRenderer.getWidth() + (EXPANDER_SIZE - EXPANDER_ICON_SIZE) / 2,
+                (height - EXPANDER_ICON_SIZE) / 2);
+
+            int[] xPoints = {0, EXPANDER_ICON_SIZE, 0};
+            int[] yPoints = {0, EXPANDER_ICON_SIZE / 2, EXPANDER_ICON_SIZE};
+            graphics.fillPolygon(xPoints, yPoints, 3);
+            graphics.drawPolygon(xPoints, yPoints, 3);
+        }
+    }
+
+    public Image getCheckmarkImage() {
+        return checkmarkImage;
+    }
+
+    public Color getPopupBorderColor() {
+        return (Color)menuPopup.getStyles().get("borderColor");
+    }
+
+    public void setPopupBorderColor(Color popupBorderColor) {
+        menuPopup.getStyles().put("borderColor", popupBorderColor);
+    }
+
+    public void setPopupBorderColor(String popupBorderColor) {
+        if (popupBorderColor == null) {
+            throw new IllegalArgumentException("popupBorderColor is null.");
+        }
+
+        menuPopup.getStyles().put("borderColor", popupBorderColor);
+    }
+}