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/16 17:16:58 UTC
svn commit: r754926 [36/38] - in /incubator/pivot/tags/v1.0: ./ charts-test/
charts-test/src/ charts-test/src/pivot/ charts-test/src/pivot/charts/
charts-test/src/pivot/charts/test/ charts/ charts/lib/ charts/src/
charts/src/pivot/ charts/src/pivot/cha...
Added: incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTextInputSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTextInputSkin.java?rev=754926&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTextInputSkin.java (added)
+++ incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTextInputSkin.java Mon Mar 16 16:16:40 2009
@@ -0,0 +1,1177 @@
+/*
+ * 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.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.awt.font.TextHitInfo;
+import java.awt.font.TextLayout;
+import java.awt.geom.Line2D;
+import java.awt.geom.Rectangle2D;
+import java.text.AttributedCharacterIterator;
+
+import pivot.collections.Dictionary;
+import pivot.wtk.ApplicationContext;
+import pivot.wtk.Clipboard;
+import pivot.wtk.Component;
+import pivot.wtk.ComponentMouseButtonListener;
+import pivot.wtk.ComponentMouseListener;
+import pivot.wtk.Cursor;
+import pivot.wtk.Dimensions;
+import pivot.wtk.Display;
+import pivot.wtk.Insets;
+import pivot.wtk.Keyboard;
+import pivot.wtk.Mouse;
+import pivot.wtk.Bounds;
+import pivot.wtk.TextInput;
+import pivot.wtk.TextInputListener;
+import pivot.wtk.TextInputCharacterListener;
+import pivot.wtk.TextInputSelectionListener;
+import pivot.wtk.Theme;
+import pivot.wtk.skin.ComponentSkin;
+
+/**
+ * Text input skin.
+ *
+ * @author gbrown
+ */
+public class TerraTextInputSkin extends ComponentSkin
+ implements TextInputListener, TextInputCharacterListener, TextInputSelectionListener {
+ private class MouseSelectionHandler
+ implements ComponentMouseListener, ComponentMouseButtonListener {
+ private class ScrollSelectionCallback implements Runnable {
+ private int x = 0;
+
+ public void run() {
+ TextInput textInput = (TextInput)getComponent();
+ int selectionStart = textInput.getSelectionStart();
+ int selectionLength = textInput.getSelectionLength();
+
+ if (x < 0) {
+ // Add the previous character to the selection
+ if (selectionStart > 0) {
+ selectionStart--;
+ selectionLength++;
+ }
+ } else {
+ // Add the next character to the selection
+ if (selectionStart + selectionLength < textInput.getCharacterCount()) {
+ selectionLength++;
+ }
+ }
+
+ textInput.setSelection(selectionStart, selectionLength);
+ }
+ }
+
+ private ScrollSelectionCallback scrollSelectionCallback = new ScrollSelectionCallback();
+ private int scrollSelectionIntervalID = -1;
+
+ private static final int SCROLL_RATE = 50;
+
+ public boolean mouseMove(Component component, int x, int y) {
+ String text = getText();
+
+ if (text.length() > 0) {
+ Display display = (Display)component;
+
+ TextInput textInput = (TextInput)getComponent();
+ x = textInput.mapPointFromAncestor(display, x, 0).x;
+
+ if (x >= 0
+ && x < textInput.getWidth()) {
+ // Stop the scroll selection timer
+ if (scrollSelectionIntervalID != -1) {
+ ApplicationContext.clearInterval(scrollSelectionIntervalID);
+ scrollSelectionIntervalID = -1;
+ }
+
+ // Get the current selection
+ int selectionStart = textInput.getSelectionStart();
+ int selectionLength = textInput.getSelectionLength();
+
+ // Get the insertion index
+ int index = getInsertionIndex(text, x);
+
+ if (index < selectionStart) {
+ selectionLength += (selectionStart - index);
+ selectionStart = index;
+ } else {
+ if (index > selectionStart + selectionLength) {
+ selectionLength = index - selectionStart;
+ }
+ }
+
+ textInput.setSelection(selectionStart, selectionLength);
+ } else {
+ scrollSelectionCallback.x = x;
+
+ if (scrollSelectionIntervalID == -1) {
+ scrollSelectionIntervalID =
+ ApplicationContext.setInterval(scrollSelectionCallback, SCROLL_RATE);
+
+ // Run the callback once now to scroll the selection immediately
+ scrollSelectionCallback.run();
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public void mouseOver(Component component) {
+ }
+
+ public void mouseOut(Component component) {
+ }
+
+ public boolean mouseDown(Component component, Mouse.Button button, int x, int y) {
+ return false;
+ }
+
+ public boolean mouseUp(Component component, Mouse.Button button, int x, int y) {
+ // Stop the scroll selection timer
+ if (scrollSelectionIntervalID != -1) {
+ ApplicationContext.clearInterval(scrollSelectionIntervalID);
+ scrollSelectionIntervalID = -1;
+ }
+
+ // Remove the display mouse listeners
+ assert (component instanceof Display);
+ component.getComponentMouseListeners().remove(this);
+ component.getComponentMouseButtonListeners().remove(this);
+
+ return false;
+ }
+
+ public void mouseClick(Component component, Mouse.Button button, int x, int y, int count) {
+ }
+ }
+
+ /**
+ * TODO This class will be used to optimize rendering of text, so we don't
+ * need to get a copy of the string via {@link TextInput#getText()}.
+ *
+ * NOTE We'll want to use this everywhere we are currently calling
+ * getText(), if possible. This means that the character iterator will need
+ * to return "*" characters when in password mode.
+ *
+ * @author gbrown
+ */
+ private static class TextInputCharacterIterator implements AttributedCharacterIterator {
+ public TextInputCharacterIterator(TextInput textInput) {
+ // TODO Need index arguments
+ }
+
+ public int getBeginIndex() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getEndIndex() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public char setIndex(int position) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getIndex() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public char current() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public char first() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public char last() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public char next() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public char previous() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getRunLimit() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getRunLimit(Attribute arg0) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getRunLimit(java.util.Set<? extends Attribute> arg0) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getRunStart() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getRunStart(Attribute arg0) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getRunStart(java.util.Set<? extends Attribute> arg0) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public Object getAttribute(Attribute arg0) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public java.util.Map<Attribute, Object> getAttributes() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public java.util.Set<Attribute> getAllAttributeKeys() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Object clone() {
+ // TODO
+ return null;
+ }
+ }
+
+ private class BlinkCursorCallback implements Runnable {
+ public void run() {
+ caretOn = !caretOn;
+
+ java.awt.Rectangle caretBounds = caretShapes[0].getBounds();
+ LineMetrics lm = font.getLineMetrics("", fontRenderContext);
+
+ int ascent = Math.round(lm.getAscent());
+ caretBounds.x += (padding.left - scrollLeft + 1);
+ caretBounds.y += (padding.top + ascent + 1);
+
+ if (caretBounds.width == 0) {
+ caretBounds.width++;
+ }
+
+ TextInput textInput = (TextInput)getComponent();
+ textInput.repaint(caretBounds.x, caretBounds.y,
+ caretBounds.width, caretBounds.height, true);
+ }
+ }
+
+ protected FontRenderContext fontRenderContext = new FontRenderContext(null, true, false);
+
+ private boolean caretOn = true;
+ private Shape[] caretShapes = null;
+ private Shape logicalHighlightShape = null;
+
+ private int scrollLeft = 0;
+
+ private BlinkCursorCallback blinkCursorCallback = new BlinkCursorCallback();
+ private int blinkCursorIntervalID = -1;
+
+ 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 Color selectionColor;
+ private Color selectionBackgroundColor;
+ private Color inactiveSelectionColor;
+ private Color inactiveSelectionBackgroundColor;
+
+ // Derived colors
+ private Color bevelColor;
+ private Color disabledBevelColor;
+
+ public TerraTextInputSkin() {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ font = theme.getFont();
+ color = theme.getColor(1);
+ disabledColor = theme.getColor(7);
+ backgroundColor = theme.getColor(11);
+ disabledBackgroundColor = theme.getColor(10);
+ borderColor = theme.getColor(7);
+ disabledBorderColor = theme.getColor(7);
+ padding = new Insets(2);
+
+ selectionColor = theme.getColor(4);
+ selectionBackgroundColor = theme.getColor(19);
+ inactiveSelectionColor = theme.getColor(1);
+ inactiveSelectionBackgroundColor = theme.getColor(9);
+
+ // Set the derived colors
+ bevelColor = TerraTheme.darken(backgroundColor);
+ disabledBevelColor = disabledBackgroundColor;
+ }
+
+ @Override
+ public void install(Component component) {
+ super.install(component);
+
+ TextInput textInput = (TextInput)component;
+ textInput.getTextInputCharacterListeners().add(this);
+ textInput.getTextInputSelectionListeners().add(this);
+
+ textInput.setCursor(Cursor.TEXT);
+
+ selectionChanged(textInput, 0, 0);
+ }
+
+ @Override
+ public void uninstall() {
+ TextInput textInput = (TextInput)getComponent();
+ textInput.getTextInputCharacterListeners().remove(this);
+ textInput.getTextInputSelectionListeners().remove(this);
+
+ textInput.setCursor(Cursor.DEFAULT);
+
+ super.uninstall();
+ }
+
+ public int getPreferredWidth(int height) {
+ TextInput textInput = (TextInput)getComponent();
+ int textSize = textInput.getTextSize();
+
+ // TODO Localize?
+ // TODO Recalculate only when font changes
+ String testString = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
+
+ Rectangle2D testStringBounds = font.getStringBounds(testString, fontRenderContext);
+ int averageCharWidth = (int)Math.round((testStringBounds.getWidth() / testString.length()));
+
+ return textSize * averageCharWidth + (padding.left + padding.right) + 2;
+ }
+
+ public int getPreferredHeight(int width) {
+ // TODO Recalculate only when font changes
+ Rectangle2D maxCharBounds = font.getMaxCharBounds(fontRenderContext);
+ int maxCharHeight = (int)Math.round(maxCharBounds.getHeight());
+
+ return maxCharHeight + (padding.top + padding.bottom) + 2;
+ }
+
+ public Dimensions getPreferredSize() {
+ return new Dimensions(getPreferredWidth(-1), getPreferredHeight(-1));
+ }
+
+ public void layout() {
+ // No-op
+ }
+
+ public void paint(Graphics2D graphics) {
+ TextInput textInput = (TextInput)getComponent();
+
+ Color backgroundColor = null;
+ Color borderColor = null;
+ Color bevelColor = null;
+
+ if (textInput.isEnabled()) {
+ backgroundColor = this.backgroundColor;
+ borderColor = this.borderColor;
+ bevelColor = this.bevelColor;
+ }
+ else {
+ backgroundColor = disabledBackgroundColor;
+ borderColor = this.disabledBorderColor;
+ bevelColor = disabledBevelColor;
+ }
+
+ // Paint the background
+ graphics.setPaint(backgroundColor);
+ Bounds bounds = new Bounds(0, 0, getWidth(), getHeight());
+ graphics.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
+
+ // Draw all lines with a 1px solid stroke
+ graphics.setStroke(new BasicStroke());
+
+ // Paint the border
+ graphics.setPaint(borderColor);
+ graphics.drawRect(0, 0, bounds.width - 1, bounds.height - 1);
+
+ // Paint the bevel
+ Line2D bevelLine = new Line2D.Double(1, 1, bounds.width - 2, 1);
+ graphics.setPaint(bevelColor);
+ graphics.draw(bevelLine);
+
+ // Paint the content
+ String text = getText();
+
+ LineMetrics lm = font.getLineMetrics("", fontRenderContext);
+ int ascent = Math.round(lm.getAscent());
+
+ graphics.translate(padding.left - scrollLeft + 1, padding.top + ascent + 1);
+
+ if (textInput.getCharacterCount() > 0) {
+ // Paint the text
+ if (fontRenderContext.isAntiAliased()) {
+ // TODO Use VALUE_TEXT_ANTIALIAS_LCD_HRGB when JDK 1.6 is
+ // available on OSX?
+ graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
+ RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+ }
+
+ if (fontRenderContext.usesFractionalMetrics()) {
+ graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
+ RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+ }
+
+ graphics.setFont(font);
+ graphics.setPaint(color);
+ graphics.drawString(text, 0, 0);
+
+ if (textInput.getSelectionLength() > 0) {
+ // Paint the selection
+ Graphics2D selectionGraphics = (Graphics2D)graphics.create();
+ selectionGraphics.clip(logicalHighlightShape.getBounds());
+
+ Color selectionColor;
+ Color selectionBackgroundColor;
+
+ if (textInput.isFocused()) {
+ selectionColor = this.selectionColor;
+ selectionBackgroundColor = this.selectionBackgroundColor;
+ } else {
+ selectionColor = inactiveSelectionColor;
+ selectionBackgroundColor = inactiveSelectionBackgroundColor;
+ }
+
+ selectionGraphics.setPaint(selectionBackgroundColor);
+ selectionGraphics.fill(logicalHighlightShape);
+
+ selectionGraphics.setPaint(selectionColor);
+ selectionGraphics.drawString(text, 0, 0);
+
+ selectionGraphics.dispose();
+ }
+ }
+
+ if (textInput.getSelectionLength() == 0
+ && textInput.isFocused()
+ && caretOn) {
+ graphics.setPaint(Color.BLACK);
+ graphics.draw(caretShapes[0]);
+ }
+ }
+
+ protected String getText() {
+ TextInput textInput = (TextInput)getComponent();
+
+ // TODO Use the internal character iterator instead of getting a copy
+ // of the string
+ String text = textInput.getText();
+
+ if (textInput.isPassword()) {
+ int n = text.length();
+ StringBuilder passwordTextBuilder = new StringBuilder(n);
+ for (int i = 0; i < n; i++) {
+ passwordTextBuilder.append("*");
+ }
+
+ text = passwordTextBuilder.toString();
+ }
+
+ return text;
+ }
+
+ protected int getInsertionIndex(String text, int x) {
+ TextLayout textLayout = new TextLayout(text, font, fontRenderContext);
+ TextHitInfo textHitInfo = textLayout.hitTestChar(x + scrollLeft - padding.left - 1, 0);
+ int index = textHitInfo.getInsertionIndex();
+
+ return index;
+ }
+
+ public void showCaret(boolean show) {
+ if (show) {
+ if (blinkCursorIntervalID == -1) {
+ blinkCursorIntervalID = ApplicationContext.setInterval(blinkCursorCallback,
+ ApplicationContext.getCursorBlinkRate());
+
+ // Run the callback once now to show the cursor immediately
+ blinkCursorCallback.run();
+ }
+ } else {
+ if (blinkCursorIntervalID != -1) {
+ ApplicationContext.clearInterval(blinkCursorIntervalID);
+ blinkCursorIntervalID = -1;
+ }
+ }
+ }
+
+ 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.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;
+ 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 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 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());
+ }
+
+ @Override
+ public boolean mouseDown(Component component, Mouse.Button button, int x, int y) {
+ if (button == Mouse.Button.LEFT) {
+ // Move the caret to the insertion point
+ TextInput textInput = (TextInput)getComponent();
+ String text = getText();
+
+ if (text.length() > 0) {
+ int index = getInsertionIndex(text, x);
+ textInput.setSelection(index, 0);
+ }
+
+ // Begin selecting text
+ MouseSelectionHandler mouseSelectionHandler = new MouseSelectionHandler();
+
+ Display display = textInput.getDisplay();
+ display.getComponentMouseListeners().add(mouseSelectionHandler);
+ display.getComponentMouseButtonListeners().add(mouseSelectionHandler);
+
+ // Set focus to the text input
+ textInput.requestFocus();
+ }
+
+ return super.mouseDown(component, button, x, y);
+ }
+
+ @Override
+ public void mouseClick(Component component, Mouse.Button button, int x, int y, int count) {
+ if (button == Mouse.Button.LEFT
+ && count > 1) {
+ TextInput textInput = (TextInput)getComponent();
+ textInput.setSelection(0, textInput.getCharacterCount());
+ }
+
+ super.mouseClick(component, button, x, y, count);
+ }
+
+ @Override
+ public void keyTyped(Component component, char character) {
+ // Ignore characters in the control range and the ASCII delete
+ // character
+ if (character > 0x1F
+ && character != 0x7F) {
+ TextInput textInput = (TextInput)getComponent();
+
+ int selectionStart = textInput.getSelectionStart();
+ int selectionLength = textInput.getSelectionLength();
+
+ if (selectionLength > 0) {
+ textInput.removeText(selectionStart, selectionLength);
+ }
+
+ if (textInput.getCharacterCount() < textInput.getMaximumLength()) {
+ textInput.insertText(character, selectionStart);
+ } else {
+ ApplicationContext.beep();
+ }
+ }
+ }
+
+ @Override
+ public boolean keyPressed(Component component, int keyCode, Keyboard.KeyLocation keyLocation) {
+ boolean consumed = false;
+
+ TextInput textInput = (TextInput)getComponent();
+
+ if (keyCode == Keyboard.KeyCode.DELETE) {
+ int selectionStart = textInput.getSelectionStart();
+ int selectionLength = textInput.getSelectionLength();
+
+ if (selectionLength > 0) {
+ // Delete any selected text
+ textInput.removeText(selectionStart, selectionLength);
+ } else {
+ // Delete the character after the caret (if any)
+ if (selectionStart < textInput.getCharacterCount()) {
+ textInput.removeText(selectionStart, 1);
+ }
+ }
+ } else if (keyCode == Keyboard.KeyCode.BACKSPACE) {
+ int selectionLength = textInput.getSelectionLength();
+
+ if (selectionLength > 0) {
+ // Delete any selected text
+ textInput.removeText(textInput.getSelectionStart(), selectionLength);
+ } else {
+ // Delete the character before the caret (if any)
+ int selectionStart = textInput.getSelectionStart();
+
+ if (selectionStart > 0) {
+ textInput.removeText(selectionStart - 1, 1);
+ }
+ }
+ } else if (keyCode == Keyboard.KeyCode.LEFT) {
+ int selectionStart = textInput.getSelectionStart();
+ int selectionLength = textInput.getSelectionLength();
+
+ if (Keyboard.isPressed(Keyboard.Modifier.SHIFT)
+ && Keyboard.isPressed(Keyboard.Modifier.CTRL)) {
+ // Add all preceding text to the selection
+ selectionLength = selectionStart + selectionLength;
+ selectionStart = 0;
+ } else if (Keyboard.isPressed(Keyboard.Modifier.SHIFT)) {
+ // Add the previous character to the selection
+ if (selectionStart > 0) {
+ selectionStart--;
+ selectionLength++;
+ }
+ } else if (Keyboard.isPressed(Keyboard.Modifier.CTRL)) {
+ // Clear the selection and move the caret to the beginning of
+ // the text
+ selectionStart = 0;
+ selectionLength = 0;
+ } else {
+ // Clear the selection and move the caret back by one
+ // character
+ if (selectionLength == 0
+ && selectionStart > 0) {
+ selectionStart--;
+ }
+
+ selectionLength = 0;
+ }
+
+ textInput.setSelection(selectionStart, selectionLength);
+ } else if (keyCode == Keyboard.KeyCode.RIGHT) {
+ int selectionStart = textInput.getSelectionStart();
+ int selectionLength = textInput.getSelectionLength();
+
+ if (Keyboard.isPressed(Keyboard.Modifier.SHIFT)
+ && Keyboard.isPressed(Keyboard.Modifier.CTRL)) {
+ // Add all subsequent text to the selection
+ selectionLength = textInput.getCharacterCount() - selectionStart;
+ } else if (Keyboard.isPressed(Keyboard.Modifier.SHIFT)) {
+ // Add the next character to the selection
+ if (selectionStart + selectionLength < textInput.getCharacterCount()) {
+ selectionLength++;
+ }
+ } else if (Keyboard.isPressed(Keyboard.Modifier.CTRL)) {
+ // Clear the selection and move the caret to the end of
+ // the text
+ selectionStart = textInput.getCharacterCount();
+ selectionLength = 0;
+ } else {
+ // Clear the selection and move the caret forward by one
+ // character
+ selectionStart += selectionLength;
+
+ if (selectionLength == 0
+ && selectionStart < textInput.getCharacterCount()) {
+ selectionStart++;
+ }
+
+ selectionLength = 0;
+ }
+
+ textInput.setSelection(selectionStart, selectionLength);
+ } else if (keyCode == Keyboard.KeyCode.A
+ && Keyboard.isPressed(Keyboard.Modifier.CTRL)) {
+ // Select all
+ textInput.setSelection(0, textInput.getCharacterCount());
+ } else if (keyCode == Keyboard.KeyCode.X
+ && Keyboard.isPressed(Keyboard.Modifier.CTRL)) {
+ // "Cut"
+ if (textInput.isPassword()) {
+ ApplicationContext.beep();
+ } else {
+ // Delete any selected text and put it on the clipboard
+ int selectionLength = textInput.getSelectionLength();
+ if (selectionLength > 0) {
+ String removedText = textInput.removeText(textInput.getSelectionStart(),
+ selectionLength);
+
+ Clipboard.getInstance().put(removedText);
+ }
+ }
+ } else if (keyCode == Keyboard.KeyCode.C
+ && Keyboard.isPressed(Keyboard.Modifier.CTRL)) {
+ // "Copy"
+ if (textInput.isPassword()) {
+ ApplicationContext.beep();
+ } else {
+ // Copy selection to clipboard
+ String selectedText = textInput.getSelectedText();
+ if (selectedText != null) {
+ Clipboard.getInstance().put(selectedText);
+ }
+ }
+ } else if (keyCode == Keyboard.KeyCode.V
+ && Keyboard.isPressed(Keyboard.Modifier.CTRL)) {
+ // "Paste"
+ Object clipboardContents = Clipboard.getInstance().get();
+
+ if (clipboardContents != null) {
+ // Paste the string representation of the content
+ String clipboardText = clipboardContents.toString();
+
+ if ((clipboardText.length()
+ + textInput.getCharacterCount()) > textInput.getMaximumLength()) {
+ ApplicationContext.beep();
+ } else {
+ // Remove any existing selection
+ int selectionLength = textInput.getSelectionLength();
+ if (selectionLength > 0) {
+ textInput.removeText(textInput.getSelectionStart(),
+ selectionLength);
+ }
+
+ // Insert the clipboard contents
+ int selectionStart = textInput.getSelectionStart();
+ textInput.insertText(clipboardText, selectionStart);
+ }
+ }
+ } else {
+ consumed = super.keyPressed(component, keyCode, keyLocation);
+ }
+
+ 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);
+
+ TextInput textInput = (TextInput)getComponent();
+
+ if (component.isFocused()) {
+ showCaret(textInput.getSelectionLength() == 0);
+
+ if (!temporary
+ && Mouse.getButtons() == 0) {
+ textInput.setSelection(0, textInput.getCharacterCount());
+ }
+ } else {
+ if (!temporary) {
+ textInput.setSelection(textInput.getSelectionStart()
+ + textInput.getSelectionLength(), 0);
+ }
+
+ showCaret(false);
+ }
+
+ repaintComponent();
+ }
+
+ // Text input events
+ public void textKeyChanged(TextInput textInput, String previousTextKey) {
+ // No-op
+ }
+
+ public void textSizeChanged(TextInput textInput, int previousTextSize) {
+ invalidateComponent();
+ }
+
+ public void maximumLengthChanged(TextInput textInput, int previousMaximumLength) {
+ // No-op
+ }
+
+ public void passwordChanged(TextInput textInput) {
+ repaintComponent();
+ }
+
+ // Text input character events
+ public void charactersInserted(TextInput textInput, int index, int count) {
+ repaintComponent();
+ }
+
+ public void charactersRemoved(TextInput textInput, int index, int count) {
+ String text = getText();
+ Rectangle2D textBounds = font.getStringBounds(text, fontRenderContext);
+
+ int textWidth = (int)textBounds.getWidth();
+ int width = getWidth();
+
+ // If the right edge of the text is less than the right inset, align
+ // the text's right edge with the inset
+ if (textWidth - scrollLeft + padding.left + 1 < width - padding.right - 1) {
+ scrollLeft = Math.max(textWidth + (padding.left + padding.right + 2) - width, 0);
+ }
+
+ repaintComponent();
+ }
+
+ public void charactersReset(TextInput textInput) {
+ repaintComponent();
+ }
+
+ // Text input selection events
+ public void selectionChanged(TextInput textInput,
+ int previousSelectionStart, int previousSelectionLength) {
+ // Update the selection bounding box
+ String text = getText();
+
+ // NOTE For some reason, TextLayout does not accept zero-length
+ // strings. This may be a bug in AWT, since an empty string should be
+ // valid, and is necessary to determine the caret shape for an empty
+ // text input.
+ // TODO Report this issue to Sun?
+ if (text.length() == 0) {
+ text = " ";
+ }
+
+ int selectionStart = textInput.getSelectionStart();
+ int selectionLength = textInput.getSelectionLength();
+
+ TextLayout textLayout = new TextLayout(text, font, fontRenderContext);
+
+ caretShapes = textLayout.getCaretShapes(selectionStart);
+ logicalHighlightShape = textLayout.getLogicalHighlightShape(selectionStart,
+ selectionStart + selectionLength);
+
+ int width = getWidth();
+
+ if (width <= padding.left + padding.right + 2) {
+ scrollLeft = 0;
+ } else {
+ if (textInput.getSelectionLength() == 0) {
+ Rectangle2D caretBounds = caretShapes[0].getBounds();
+ int caretLeft = (int)caretBounds.getX();
+
+ if (caretLeft - scrollLeft < 0) {
+ // Ensure that the left edge of caret is visible
+ scrollLeft = caretLeft;
+ } else {
+ // Ensure that the right edge of the caret is visible
+ int caretRight = (int)caretBounds.getMaxX();
+
+ if (caretRight - scrollLeft + padding.left + 1 > width - padding.right - 1) {
+ scrollLeft = Math.max(caretRight
+ - (width - (padding.left + padding.right + 2)), 0);
+ }
+ }
+ } else {
+ Rectangle2D logicalHighlightBounds = logicalHighlightShape.getBounds();
+ int logicalHighlightLeft = (int)logicalHighlightBounds.getX();
+
+ if (logicalHighlightLeft - scrollLeft < 0
+ && previousSelectionStart > selectionStart) {
+ // Ensure that the left edge of the highlight is visible
+ scrollLeft = logicalHighlightLeft;
+ } else {
+ // Ensure that the right edge of the highlight is visible
+ int logicalHighlightRight = (int)logicalHighlightBounds.getMaxX();
+
+ if (logicalHighlightRight - scrollLeft + padding.left + 1 > width - padding.right - 1) {
+ scrollLeft = Math.max(logicalHighlightRight
+ - (width - (padding.left + padding.right + 2)), 0);
+ }
+ }
+ }
+ }
+
+ showCaret(textInput.isFocused()
+ && selectionLength == 0);
+
+ repaintComponent();
+ }
+}
Added: incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTheme.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTheme.java?rev=754926&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTheme.java (added)
+++ incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTheme.java Mon Mar 16 16:16:40 2009
@@ -0,0 +1,297 @@
+/*
+ * 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.net.URL;
+
+import pivot.collections.List;
+import pivot.serialization.JSONSerializer;
+import pivot.util.Resources;
+import pivot.wtk.Alert;
+import pivot.wtk.ApplicationContext;
+import pivot.wtk.Border;
+import pivot.wtk.Calendar;
+import pivot.wtk.Checkbox;
+import pivot.wtk.Dialog;
+import pivot.wtk.Expander;
+import pivot.wtk.FlowPane;
+import pivot.wtk.Form;
+import pivot.wtk.Frame;
+import pivot.wtk.Label;
+import pivot.wtk.LinkButton;
+import pivot.wtk.ListButton;
+import pivot.wtk.ListView;
+import pivot.wtk.MenuBar;
+import pivot.wtk.MenuButton;
+import pivot.wtk.MenuPopup;
+import pivot.wtk.Menu;
+import pivot.wtk.MessageType;
+import pivot.wtk.Meter;
+import pivot.wtk.Palette;
+import pivot.wtk.Panorama;
+import pivot.wtk.Prompt;
+import pivot.wtk.PushButton;
+import pivot.wtk.RadioButton;
+import pivot.wtk.Rollup;
+import pivot.wtk.ScrollBar;
+import pivot.wtk.ScrollPane;
+import pivot.wtk.Separator;
+import pivot.wtk.Sheet;
+import pivot.wtk.Spinner;
+import pivot.wtk.SplitPane;
+import pivot.wtk.TablePane;
+import pivot.wtk.TableViewHeader;
+import pivot.wtk.TableView;
+import pivot.wtk.TabPane;
+import pivot.wtk.TextInput;
+import pivot.wtk.Theme;
+import pivot.wtk.Tooltip;
+import pivot.wtk.TreeView;
+import pivot.wtk.media.Image;
+
+/**
+ * Terra theme.
+ *
+ * @author gbrown
+ * @author tvolkert
+ */
+public final class TerraTheme extends Theme {
+ private String scheme;
+
+ private Resources resources = null;
+
+ private Font font;
+ private Color[] colors;
+
+ public TerraTheme() {
+ this("default");
+ }
+
+ public TerraTheme(String scheme) {
+ if (scheme == null) {
+ throw new IllegalArgumentException("scheme is null.");
+ }
+
+ this.scheme = scheme;
+
+ componentSkinMap.put(Alert.class, TerraAlertSkin.class);
+ componentSkinMap.put(Border.class, TerraBorderSkin.class);
+ componentSkinMap.put(Checkbox.class, TerraCheckboxSkin.class);
+ componentSkinMap.put(Calendar.class, TerraCalendarSkin.class);
+ componentSkinMap.put(Dialog.class, TerraDialogSkin.class);
+ componentSkinMap.put(Expander.class, TerraExpanderSkin.class);
+ componentSkinMap.put(Form.class, TerraFormSkin.class);
+ componentSkinMap.put(FlowPane.class, TerraFlowPaneSkin.class);
+ componentSkinMap.put(Frame.class, TerraFrameSkin.class);
+ componentSkinMap.put(Label.class, TerraLabelSkin.class);
+ componentSkinMap.put(LinkButton.class, TerraLinkButtonSkin.class);
+ componentSkinMap.put(ListButton.class, TerraListButtonSkin.class);
+ componentSkinMap.put(ListView.class, TerraListViewSkin.class);
+ componentSkinMap.put(Menu.class, TerraMenuSkin.class);
+ componentSkinMap.put(Menu.Item.class, TerraMenuItemSkin.class);
+ componentSkinMap.put(MenuBar.class, TerraMenuBarSkin.class);
+ componentSkinMap.put(MenuBar.Item.class, TerraMenuBarItemSkin.class);
+ componentSkinMap.put(MenuButton.class, TerraMenuButtonSkin.class);
+ componentSkinMap.put(MenuPopup.class, TerraMenuPopupSkin.class);
+ componentSkinMap.put(Meter.class, TerraMeterSkin.class);
+ componentSkinMap.put(Palette.class, TerraPaletteSkin.class);
+ componentSkinMap.put(Panorama.class, TerraPanoramaSkin.class);
+ componentSkinMap.put(Prompt.class, TerraPromptSkin.class);
+ componentSkinMap.put(PushButton.class, TerraPushButtonSkin.class);
+ componentSkinMap.put(RadioButton.class, TerraRadioButtonSkin.class);
+ componentSkinMap.put(Rollup.class, TerraRollupSkin.class);
+ componentSkinMap.put(ScrollBar.class, TerraScrollBarSkin.class);
+ componentSkinMap.put(ScrollPane.class, TerraScrollPaneSkin.class);
+ componentSkinMap.put(ScrollPane.Corner.class, TerraScrollPaneCornerSkin.class);
+ componentSkinMap.put(Separator.class, TerraSeparatorSkin.class);
+ componentSkinMap.put(Sheet.class, TerraSheetSkin.class);
+ componentSkinMap.put(Spinner.class, TerraSpinnerSkin.class);
+ componentSkinMap.put(SplitPane.class, TerraSplitPaneSkin.class);
+ componentSkinMap.put(TablePane.class, TerraTablePaneSkin.class);
+ componentSkinMap.put(TableViewHeader.class, TerraTableViewHeaderSkin.class);
+ componentSkinMap.put(TableView.class, TerraTableViewSkin.class);
+ componentSkinMap.put(TabPane.class, TerraTabPaneSkin.class);
+ componentSkinMap.put(TextInput.class, TerraTextInputSkin.class);
+ componentSkinMap.put(Tooltip.class, TerraTooltipSkin.class);
+ componentSkinMap.put(TreeView.class, TerraTreeViewSkin.class);
+
+ componentSkinMap.put(TerraExpanderSkin.ShadeButton.class, TerraExpanderSkin.ShadeButtonSkin.class);
+ componentSkinMap.put(TerraFrameSkin.FrameButton.class, TerraFrameSkin.FrameButtonSkin.class);
+ componentSkinMap.put(TerraRollupSkin.RollupButton.class, TerraRollupSkin.RollupButtonSkin.class);
+ componentSkinMap.put(TerraScrollBarSkin.ScrollButton.class, TerraScrollBarSkin.ScrollButtonSkin.class);
+ componentSkinMap.put(TerraScrollBarSkin.ScrollHandle.class, TerraScrollBarSkin.ScrollHandleSkin.class);
+ componentSkinMap.put(TerraSpinnerSkin.SpinButton.class, TerraSpinnerSkin.SpinButtonSkin.class);
+ componentSkinMap.put(TerraSpinnerSkin.SpinnerContent.class, TerraSpinnerSkin.SpinnerContentSkin.class);
+ componentSkinMap.put(TerraSplitPaneSkin.Splitter.class, TerraSplitPaneSkin.SplitterSkin.class);
+ componentSkinMap.put(TerraSplitPaneSkin.SplitterShadow.class, TerraSplitPaneSkin.SplitterShadowSkin.class);
+ componentSkinMap.put(TerraTabPaneSkin.TabButton.class, TerraTabPaneSkin.TabButtonSkin.class);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void install() {
+ try {
+ String baseName = getClass().getName() + "_" + scheme;
+ resources = new Resources(baseName);
+ } catch(Exception exception) {
+ throw new RuntimeException(exception);
+ }
+
+ font = Font.decode(JSONSerializer.getString(resources, "font"));
+
+ List<String> colorCodes = (List<String>)JSONSerializer.getList(resources, "colors");
+ colors = new Color[colorCodes.getLength() * 3];
+
+ for (int i = 0, n = colorCodes.getLength(); i < n; i++) {
+ int baseIndex = i * 3 + 1;
+ Color baseColor = Color.decode(colorCodes.get(i));
+
+ colors[baseIndex] = baseColor;
+ colors[baseIndex - 1] = darken(baseColor);
+ colors[baseIndex + 1] = brighten(baseColor);
+ }
+ }
+
+ public void uninstall() {
+ resources = null;
+ }
+
+ public Font getFont() {
+ return font;
+ }
+
+ public Color getColor(int index) {
+ return colors[index];
+ }
+
+ public Image getMessageIcon(MessageType messageType) {
+ String messageIconName;
+
+ switch (messageType) {
+ case ERROR: {
+ messageIconName = JSONSerializer.getString(resources, "errorIcon");
+ break;
+ }
+
+ case WARNING: {
+ messageIconName = JSONSerializer.getString(resources, "warningIcon");
+ break;
+ }
+
+ case QUESTION: {
+ messageIconName = JSONSerializer.getString(resources, "questionIcon");
+ break;
+ }
+
+ case INFO: {
+ messageIconName = JSONSerializer.getString(resources, "infoIcon");
+ break;
+ }
+
+ case APPLICATION: {
+ messageIconName = null;
+ break;
+ }
+
+ default: {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ Image messageIcon = null;
+
+ if (messageIconName != null) {
+ URL location = getClass().getResource(messageIconName);
+ messageIcon = (Image)ApplicationContext.getResourceCache().get(location);
+
+ if (messageIcon == null) {
+ messageIcon = Image.load(location);
+ ApplicationContext.getResourceCache().put(location, messageIcon);
+ }
+ }
+
+ return messageIcon;
+ }
+
+ public Image getSmallMessageIcon(MessageType messageType) {
+ String smallMessageIconName;
+
+ switch (messageType) {
+ case ERROR: {
+ smallMessageIconName = JSONSerializer.getString(resources, "smallErrorIcon");
+ break;
+ }
+
+ case WARNING: {
+ smallMessageIconName = JSONSerializer.getString(resources, "smallWarningIcon");
+ break;
+ }
+
+ case QUESTION: {
+ smallMessageIconName = JSONSerializer.getString(resources, "smallQuestionIcon");
+ break;
+ }
+
+ case INFO: {
+ smallMessageIconName = JSONSerializer.getString(resources, "smallInfoIcon");
+ break;
+ }
+
+ case APPLICATION: {
+ smallMessageIconName = null;
+ break;
+ }
+
+ default: {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ Image smallMessageIcon = null;
+
+ if (smallMessageIconName != null) {
+ URL location = getClass().getResource(smallMessageIconName);
+ smallMessageIcon = (Image)ApplicationContext.getResourceCache().get(location);
+
+ if (smallMessageIcon == null) {
+ smallMessageIcon = Image.load(location);
+ ApplicationContext.getResourceCache().put(location, smallMessageIcon);
+ }
+ }
+
+ return smallMessageIcon;
+ }
+
+ public Resources getResources() {
+ return resources;
+ }
+
+ public static Color brighten(Color color) {
+ return adjustBrightness(color, 0.1f);
+ }
+
+ public static Color darken(Color color) {
+ return adjustBrightness(color, -0.1f);
+ }
+
+ private static Color adjustBrightness(Color color, float adjustment) {
+ float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
+ hsb[2] = Math.min(Math.max(hsb[2] + adjustment, 0f), 1f);
+ int rgb = Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]);
+ return new Color((color.getAlpha() << 24) | (rgb & 0xffffff));
+ }
+}
Added: incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTheme_default.json
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTheme_default.json?rev=754926&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTheme_default.json (added)
+++ incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTheme_default.json Mon Mar 16 16:16:40 2009
@@ -0,0 +1,23 @@
+{ font: "Verdana 11",
+
+ colors: [
+ "#000000",
+ "#ffffff",
+ "#999999",
+ "#dddcd5",
+ "#2b5580",
+ "#3c77b2",
+ "#14538b",
+ "#b0000f"
+ ],
+
+ errorIcon: "message_type-error-32x32.png",
+ warningIcon: "message_type-warning-32x32.png",
+ questionIcon: "message_type-question-32x32.png",
+ infoIcon: "message_type-info-32x32.png",
+
+ smallErrorIcon: "message_type-error-16x16.png",
+ smallWarningIcon: "message_type-warning-16x16.png",
+ smallQuestionIcon: "message_type-question-16x16.png",
+ smallInfoIcon: "message_type-info-16x16.png"
+}
Added: incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTheme_test.json
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTheme_test.json?rev=754926&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTheme_test.json (added)
+++ incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTheme_test.json Mon Mar 16 16:16:40 2009
@@ -0,0 +1,23 @@
+{ font: "Verdana 11",
+
+ colors: [
+ "#404039",
+ "#ffffff",
+ "#998e8a",
+ "#e6e2dc",
+ "#cc6600",
+ "#ff7300",
+ "#851506",
+ "#a32900"
+ ],
+
+ errorIcon: "message_type-error-32x32.png",
+ warningIcon: "message_type-warning-32x32.png",
+ questionIcon: "message_type-question-32x32.png",
+ infoIcon: "message_type-info-32x32.png",
+
+ smallErrorIcon: "message_type-error-16x16.png",
+ smallWarningIcon: "message_type-warning-16x16.png",
+ smallQuestionIcon: "message_type-question-16x16.png",
+ smallInfoIcon: "message_type-info-16x16.png"
+}
Added: incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTooltipSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTooltipSkin.java?rev=754926&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTooltipSkin.java (added)
+++ incubator/pivot/tags/v1.0/wtk/src/pivot/wtk/skin/terra/TerraTooltipSkin.java Mon Mar 16 16:16:40 2009
@@ -0,0 +1,202 @@
+/*
+ * 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 pivot.util.Vote;
+import pivot.wtk.Border;
+import pivot.wtk.Component;
+import pivot.wtk.ComponentMouseListener;
+import pivot.wtk.ComponentMouseButtonListener;
+import pivot.wtk.ComponentMouseWheelListener;
+import pivot.wtk.ComponentKeyListener;
+import pivot.wtk.Display;
+import pivot.wtk.Insets;
+import pivot.wtk.Keyboard;
+import pivot.wtk.Label;
+import pivot.wtk.Mouse;
+import pivot.wtk.Theme;
+import pivot.wtk.Tooltip;
+import pivot.wtk.TooltipListener;
+import pivot.wtk.Window;
+import pivot.wtk.effects.Transition;
+import pivot.wtk.effects.TransitionListener;
+import pivot.wtk.skin.WindowSkin;
+
+/**
+ * Tooltip skin.
+ *
+ * @author gbrown
+ */
+public class TerraTooltipSkin extends WindowSkin implements TooltipListener {
+ private class CloseHandler implements ComponentMouseListener,
+ ComponentMouseButtonListener, ComponentMouseWheelListener,
+ ComponentKeyListener {
+ // Component mouse events
+ public boolean mouseMove(Component component, int x, int y) {
+ Tooltip tooltip = (Tooltip)getComponent();
+ tooltip.close();
+ return false;
+ }
+
+ public void mouseOver(Component component) {
+ }
+
+ public void mouseOut(Component component) {
+ }
+
+ public boolean mouseDown(Component component, Mouse.Button button, int x, int y) {
+ Tooltip tooltip = (Tooltip)getComponent();
+ tooltip.close();
+ return false;
+ }
+
+ public boolean mouseUp(Component component, Mouse.Button button, int x, int y) {
+ return false;
+ }
+
+ public void mouseClick(Component component, Mouse.Button button, int x, int y, int count) {
+ }
+
+ public boolean mouseWheel(Component component, Mouse.ScrollType scrollType,
+ int scrollAmount, int wheelRotation, int x, int y) {
+ Tooltip tooltip = (Tooltip)getComponent();
+ tooltip.close();
+ return false;
+ }
+
+ // Component key events
+ public void keyTyped(Component component, char character) {
+ }
+
+ public boolean keyPressed(Component component, int keyCode, Keyboard.KeyLocation keyLocation) {
+ Tooltip tooltip = (Tooltip)getComponent();
+ tooltip.close();
+ return false;
+ }
+
+ public boolean keyReleased(Component component, int keyCode, Keyboard.KeyLocation keyLocation) {
+ return false;
+ }
+ }
+
+ private Label label = new Label();
+ private Border border = new Border();
+
+ private CloseHandler closeHandler = new CloseHandler();
+ private Transition closeTransition = null;
+
+ private static final int CLOSE_TRANSITION_DURATION = 750;
+ private static final int CLOSE_TRANSITION_RATE = 30;
+
+ public TerraTooltipSkin() {
+ setBackgroundColor((Color)null);
+
+ // Add the label to the border
+ border.setContent(label);
+
+ // Apply the default styles
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ Component.StyleDictionary labelStyles = label.getStyles();
+ labelStyles.put("font", theme.getFont());
+ labelStyles.put("color", Color.BLACK);
+
+ Component.StyleDictionary borderStyles = border.getStyles();
+ borderStyles.put("backgroundColor", new Color(0xff, 0xff, 0xe0, 0xf0));
+ borderStyles.put("color", Color.BLACK);
+ borderStyles.put("padding", new Insets(2));
+ }
+
+ @Override
+ public void install(Component component) {
+ super.install(component);
+
+ Tooltip tooltip = (Tooltip)component;
+ tooltip.setContent(border);
+ tooltip.getTooltipListeners().add(this);
+
+ label.setText(tooltip.getText());
+ }
+
+ @Override
+ public void uninstall() {
+ Tooltip tooltip = (Tooltip)getComponent();
+ tooltip.setContent(null);
+ tooltip.getTooltipListeners().remove(this);
+ }
+
+ @Override
+ public void windowOpened(Window window) {
+ super.windowOpened(window);
+
+ // Add this as a display mouse and key listener
+ Display display = window.getDisplay();
+ display.getComponentMouseListeners().add(closeHandler);
+ display.getComponentMouseButtonListeners().add(closeHandler);
+ display.getComponentMouseWheelListeners().add(closeHandler);
+ display.getComponentKeyListeners().add(closeHandler);
+ }
+
+ @Override
+ 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) {
+ window.close();
+ }
+ });
+
+ vote = Vote.DEFER;
+ } else {
+ vote = (closeTransition.isRunning()) ? Vote.DEFER : Vote.APPROVE;
+ }
+
+ return vote;
+ }
+
+ @Override
+ public void windowCloseVetoed(Window window, Vote reason) {
+ super.windowCloseVetoed(window, reason);
+
+ if (reason == Vote.DENY
+ && closeTransition != null) {
+ closeTransition.stop();
+ }
+ }
+
+ @Override
+ public void windowClosed(Window window, Display display) {
+ super.windowClosed(window, display);
+
+ // Remove this as a display mouse and key listener
+ display.getComponentMouseListeners().remove(closeHandler);
+ display.getComponentMouseButtonListeners().remove(closeHandler);
+ display.getComponentMouseWheelListeners().remove(closeHandler);
+ display.getComponentKeyListeners().remove(closeHandler);
+
+ closeTransition = null;
+ }
+
+ public void textChanged(Tooltip tooltip, String previousText) {
+ label.setText(tooltip.getText());
+ }
+}