Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/RulerSkin.java URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/RulerSkin.java?rev=1913470&r1=1913469&r2=1913470&view=diff ============================================================================== --- pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/RulerSkin.java (original) +++ pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/RulerSkin.java Tue Oct 31 19:15:47 2023 @@ -1,557 +1,557 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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 org.apache.pivot.wtk.skin; - -import java.awt.Color; -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.font.LineMetrics; -import java.awt.geom.Rectangle2D; -import java.text.StringCharacterIterator; - -import org.apache.pivot.collections.Dictionary; -import org.apache.pivot.collections.Sequence; -import org.apache.pivot.util.Utils; -import org.apache.pivot.wtk.Borders; -import org.apache.pivot.wtk.Component; -import org.apache.pivot.wtk.CSSColor; -import org.apache.pivot.wtk.GraphicsUtilities; -import org.apache.pivot.wtk.Insets; -import org.apache.pivot.wtk.Orientation; -import org.apache.pivot.wtk.Platform; -import org.apache.pivot.wtk.Ruler; -import org.apache.pivot.wtk.RulerListener; -import org.apache.pivot.wtk.Theme; - -public class RulerSkin extends ComponentSkin implements RulerListener { - private static final int MAJOR_SIZE = 10; - private static final int MINOR_SIZE = 8; - private static final int REGULAR_SIZE = 5; - - private Color color; - private Color backgroundColor; - private int markerSpacing; - private Insets markerInsets; - private boolean flip; - private Borders borders; - private int majorDivision; - private int minorDivision; - private boolean showMajorNumbers; - private boolean showMinorNumbers; - private Font font; - private float charWidth, charHeight, descent; - - public RulerSkin() { - // For now the default colors are not from the Theme. - setColor(Color.BLACK); - setBackgroundColor(CSSColor.LightYellow.getColor()); - - markerSpacing = 5; - markerInsets = new Insets(0); - flip = false; - borders = Borders.ALL; - majorDivision = 4; - minorDivision = 2; - showMajorNumbers = false; - showMinorNumbers = false; - - Theme theme = currentTheme(); - setFont(theme.getFont()); - } - - @Override - public void install(Component component) { - super.install(component); - - Ruler ruler = (Ruler) component; - ruler.getRulerListeners().add(this); - } - - @Override - public void layout() { - // No-op - } - - @Override - public int getPreferredHeight(int width) { - Ruler ruler = (Ruler) getComponent(); - Orientation orientation = ruler.getOrientation(); - - // Give a little extra height if showing numbers - return (orientation == Orientation.HORIZONTAL) - ? ((showMajorNumbers || showMinorNumbers) - ? ((int) Math.ceil(charHeight) + MAJOR_SIZE + 5) : MAJOR_SIZE * 2) : 0; - } - - @Override - public int getPreferredWidth(int height) { - Ruler ruler = (Ruler) getComponent(); - Orientation orientation = ruler.getOrientation(); - - // Give a little extra width if showing numbers - return (orientation == Orientation.VERTICAL) - ? ((showMajorNumbers || showMinorNumbers) - ? ((int) Math.ceil(charWidth) + MAJOR_SIZE + 5) : MAJOR_SIZE * 2) : 0; - } - - private void showNumber(Graphics2D graphics, FontRenderContext fontRenderContext, int number, - int x, int y) { - String num = Integer.toString(number); - - StringCharacterIterator line; - GlyphVector glyphVector; - Rectangle2D textBounds; - float width, height; - float fx, fy; - - Ruler ruler = (Ruler) getComponent(); - Orientation orientation = ruler.getOrientation(); - - switch (orientation) { - case HORIZONTAL: - // Draw the whole number just off the tip of the line given by (x,y) - line = new StringCharacterIterator(num); - glyphVector = font.createGlyphVector(fontRenderContext, line); - textBounds = glyphVector.getLogicalBounds(); - width = (float) textBounds.getWidth(); - height = (float) textBounds.getHeight(); - fx = (float) x - (width / 2.0f); - if (flip) { - fy = (float) (y - 2); - } else { - fy = (float) (y - 1) + height; - } - graphics.drawGlyphVector(glyphVector, fx, fy); - break; - case VERTICAL: - // Draw the number one digit at a time, vertically just off the tip of the line - if (flip) { - fx = (float) (x - 1) - charWidth; - } else { - fx = (float) (x + 3); - } - int numDigits = num.length(); - float heightAdjust = (numDigits % 2 == 1) ? charHeight / 2.0f : 0.0f; - for (int i = 0; i < numDigits; i++) { - line = new StringCharacterIterator(num.substring(i, i + 1)); - glyphVector = font.createGlyphVector(fontRenderContext, line); - int midDigit = (numDigits + 1) / 2; - if (i <= midDigit) { - fy = (float) y + heightAdjust - descent - (float) (midDigit - i - 1) * charHeight; - } else { - fy = (float) y + heightAdjust - descent + (float) (i - midDigit - 1) * charHeight; - } - graphics.drawGlyphVector(glyphVector, fx, fy); - } - break; - default: - break; - } - } - - @Override - public void paint(Graphics2D graphics) { - int width = getWidth(); - int height = getHeight(); - - int top = markerInsets.top; - int left = markerInsets.left; - int bottom = height - markerInsets.bottom; - int right = width - markerInsets.right; - - Ruler ruler = (Ruler) getComponent(); - - graphics.setColor(backgroundColor); - graphics.fillRect(0, 0, width, height); - - graphics.setColor(color); - GraphicsUtilities.drawBorders(graphics, borders, 0, 0, height - 1, width - 1); - - height -= markerInsets.getHeight(); - width -= markerInsets.getWidth(); - - FontRenderContext fontRenderContext = showMajorNumbers || showMinorNumbers - ? GraphicsUtilities.prepareForText(graphics, font, color) : null; - - int start, end2, end3, end4; - - Orientation orientation = ruler.getOrientation(); - switch (orientation) { - case HORIZONTAL: - start = flip ? bottom - 1 : top; - end2 = flip ? (start - (MAJOR_SIZE - 1)) : (MAJOR_SIZE - 1); - end3 = flip ? (start - (MINOR_SIZE - 1)) : (MINOR_SIZE - 1); - end4 = flip ? (start - (REGULAR_SIZE - 1)) : (REGULAR_SIZE - 1); - - for (int i = 0, n = right / markerSpacing + 1; i < n; i++) { - int x = i * markerSpacing + left; - - if (majorDivision != 0 && i % majorDivision == 0) { - graphics.drawLine(x, start, x, end2); - // Don't show any numbers at 0 -- make a style for this? - if (showMajorNumbers && i > 0) { - showNumber(graphics, fontRenderContext, i, x, end2); - } - } else if (minorDivision != 0 && i % minorDivision == 0) { - graphics.drawLine(x, start, x, end3); - if (showMinorNumbers && i > 0) { - // Show the minor numbers at the same y point as the major - showNumber(graphics, fontRenderContext, i, x, end2); - } - } else { - graphics.drawLine(x, start, x, end4); - } - } - break; - - case VERTICAL: - start = flip ? right - 1 : left; - end2 = flip ? (start - (MAJOR_SIZE - 1)) : (MAJOR_SIZE - 1); - end3 = flip ? (start - (MINOR_SIZE - 1)) : (MINOR_SIZE - 1); - end4 = flip ? (start - (REGULAR_SIZE - 1)) : (REGULAR_SIZE - 1); - - for (int i = 0, n = bottom / markerSpacing + 1; i < n; i++) { - int y = i * markerSpacing + top; - - if (majorDivision != 0 && i % majorDivision == 0) { - graphics.drawLine(start, y, end2, y); - // Don't show any numbers at 0 -- make a style for this? - if (showMajorNumbers && i > 0) { - showNumber(graphics, fontRenderContext, i, end2, y); - } - } else if (minorDivision != 0 && i % minorDivision == 0) { - graphics.drawLine(start, y, end3, y); - if (showMinorNumbers && i > 0) { - showNumber(graphics, fontRenderContext, i, end3, y); - } - } else { - graphics.drawLine(start, y, end4, y); - } - } - break; - - default: - break; - } - } - - @Override - public void orientationChanged(Ruler ruler) { - invalidateComponent(); - } - - /** - * @return The interval at which the "major" (that is, the long) - * markers are drawn. - */ - public final int getMajorDivision() { - return majorDivision; - } - - /** - * Set the major division interval. - * - * @param major The number of markers interval at which to draw - * a "major" (long) marker. Can be zero to not draw any major - * markers. - */ - public final void setMajorDivision(int major) { - Utils.checkNonNegative(major, "majorDivision"); - - // TODO: check for sanity of major vs. minor here?? - this.majorDivision = major; - repaintComponent(); - } - - public final void setMajorDivision(Number major) { - Utils.checkNull(major, "majorDivision"); - - setMajorDivision(major.intValue()); - } - - /** - * @return The interval at which the "minor" (that is, the slightly - * longer than normal) markers are drawn. - */ - public final int getMinorDivision() { - return minorDivision; - } - - /** - * Set the minor division interval. - * - * @param minor The number of markers interval at which to draw - * a "minor" (slightly longer than normal) marker. Can be zero - * to not draw any minor markers. - */ - public final void setMinorDivision(int minor) { - Utils.checkNonNegative(minor, "minorDivision"); - - // TODO: check for sanity of major vs. minor here?? - this.minorDivision = minor; - repaintComponent(); - } - - public final void setMinorDivision(Number minor) { - Utils.checkNull(minor, "minorDivision"); - - setMinorDivision(minor.intValue()); - } - - /** - * @return The number of pixels interval at which to draw markers. - */ - public final int getMarkerSpacing() { - return markerSpacing; - } - - /** - * Set the number of pixels interval at which to draw the markers. - * - * @param spacing The number of pixels between markers (must be {@code >= 1}). - */ - public final void setMarkerSpacing(int spacing) { - Utils.checkPositive(spacing, "markerSpacing"); - - this.markerSpacing = spacing; - invalidateComponent(); - } - - public final void setMarkerSpacing(Number spacing) { - Utils.checkNull(spacing, "markerSpacing"); - - setMarkerSpacing(spacing.intValue()); - } - - /** - * @return Whether the ruler is "flipped", that is the markers - * start from the inside rather than the outside. - */ - public final boolean getFlip() { - return flip; - } - - public final void setFlip(boolean flip) { - this.flip = flip; - } - - /** - * @return Whether to display numbers at each major division. - */ - public final boolean getShowMajorNumbers() { - return showMajorNumbers; - } - - /** - * Sets the flag to say whether to show numbers at each major division. - * - * @param showMajorNumbers Whether numbers should be shown for major divisions. - */ - public final void setShowMajorNumbers(boolean showMajorNumbers) { - this.showMajorNumbers = showMajorNumbers; - invalidateComponent(); - } - - /** - * @return Whether to display numbers at each minor division. - */ - public final boolean getShowMinorNumbers() { - return showMinorNumbers; - } - - /** - * Sets the flag to say whether to show numbers at each minor division. - * - * @param showMinorNumbers Whether numbers should be shown for minor divisions. - */ - public final void setShowMinorNumbers(boolean showMinorNumbers) { - this.showMinorNumbers = showMinorNumbers; - invalidateComponent(); - } - - /** - * @return The border configuration for this ruler. - */ - public final Borders getBorders() { - return borders; - } - - public final void setBorders(Borders borders) { - Utils.checkNull(borders, "borders"); - - this.borders = borders; - repaintComponent(); - } - - /** - * @return The insets for the markers (on each edge). - */ - public final Insets getMarkerInsets() { - return markerInsets; - } - - public final void setMarkerInsets(Insets insets) { - Utils.checkNull(insets, "markerInsets"); - - this.markerInsets = insets; - repaintComponent(); - } - - public final void setMarkerInsets(Dictionary<String, ?> insets) { - setMarkerInsets(new Insets(insets)); - } - - public final void setMarkerInsets(Sequence<?> insets) { - setMarkerInsets(new Insets(insets)); - } - - public final void setMarkerInsets(int insets) { - setMarkerInsets(new Insets(insets)); - } - - public final void setMarkerInsets(Number insets) { - setMarkerInsets(new Insets(insets)); - } - - public final void setMarkerInsets(String insets) { - setMarkerInsets(Insets.decode(insets)); - } - - /** - * Returns the foreground color for the markers of the ruler. - * - * @return The foreground (marker) color. - */ - public final Color getColor() { - return color; - } - - /** - * Sets the foreground color for the markers of the ruler. - * - * @param color The foreground (that is, the marker) color. - */ - public final void setColor(Color color) { - Utils.checkNull(color, "color"); - - this.color = color; - repaintComponent(); - } - - /** - * Sets the foreground color for the markers of the ruler. - * - * @param color Any of the {@linkplain GraphicsUtilities#decodeColor color - * values recognized by Pivot}. - */ - public final void setColor(String color) { - setColor(GraphicsUtilities.decodeColor(color, "color")); - } - - public final void setColor(int color) { - Theme theme = currentTheme(); - setColor(theme.getColor(color)); - } - - /** - * Returns the background color of the ruler. - * - * @return The current background color. - */ - public final Color getBackgroundColor() { - return backgroundColor; - } - - /** - * Sets the background color of the ruler. - * - * @param backgroundColor New background color value (can be {@code null} - * for a transparent background). - */ - public final void setBackgroundColor(Color backgroundColor) { - this.backgroundColor = backgroundColor; - repaintComponent(); - } - - /** - * Sets the background color of the ruler. - * - * @param backgroundColor Any of the - * {@linkplain GraphicsUtilities#decodeColor color values recognized by - * Pivot}. - */ - public final void setBackgroundColor(String backgroundColor) { - setBackgroundColor(GraphicsUtilities.decodeColor(backgroundColor, "backgroundColor")); - } - - public final void setBackgroundColor(int backgroundColor) { - Theme theme = currentTheme(); - setBackgroundColor(theme.getColor(backgroundColor)); - } - - /** - * @return The font used to format division numbers (if enabled). - */ - public final Font getFont() { - return font; - } - - /** - * Sets the font used in rendering the Ruler's text. - * - * @param font The new font to use. - */ - public final void setFont(Font font) { - Utils.checkNull(font, "font"); - - // The font we will use is the same name and style, but a 11 pt type - this.font = font.deriveFont(11.0f); - - // Make some size calculations for the drawing code - FontRenderContext fontRenderContext = Platform.getFontRenderContext(); - GlyphVector glyphVector = this.font.createGlyphVector(fontRenderContext, "0"); - Rectangle2D textBounds = glyphVector.getLogicalBounds(); - this.charWidth = (float) textBounds.getWidth(); - // Since we're just drawing numbers, the line spacing can be just the ascent value for the font - LineMetrics lm = this.font.getLineMetrics("0", fontRenderContext); - this.charHeight = lm.getAscent(); - this.descent = lm.getDescent(); - - invalidateComponent(); - } - - /** - * Sets the font used in rendering the Ruler's text. - * - * @param font A {@link ComponentSkin#decodeFont(String) font specification} - */ - public final void setFont(String font) { - setFont(decodeFont(font)); - } - - /** - * Sets the font used in rendering the Ruler's text. - * - * @param font A dictionary {@link Theme#deriveFont describing a font} - */ - public final void setFont(Dictionary<String, ?> font) { - setFont(Theme.deriveFont(font)); - } - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you 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 org.apache.pivot.wtk.skin; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.LineMetrics; +import java.awt.geom.Rectangle2D; +import java.text.StringCharacterIterator; + +import org.apache.pivot.collections.Dictionary; +import org.apache.pivot.collections.Sequence; +import org.apache.pivot.util.Utils; +import org.apache.pivot.wtk.Borders; +import org.apache.pivot.wtk.Component; +import org.apache.pivot.wtk.CSSColor; +import org.apache.pivot.wtk.GraphicsUtilities; +import org.apache.pivot.wtk.Insets; +import org.apache.pivot.wtk.Orientation; +import org.apache.pivot.wtk.Platform; +import org.apache.pivot.wtk.Ruler; +import org.apache.pivot.wtk.RulerListener; +import org.apache.pivot.wtk.Theme; + +public class RulerSkin extends ComponentSkin implements RulerListener { + private static final int MAJOR_SIZE = 10; + private static final int MINOR_SIZE = 8; + private static final int REGULAR_SIZE = 5; + + private Color color; + private Color backgroundColor; + private int markerSpacing; + private Insets markerInsets; + private boolean flip; + private Borders borders; + private int majorDivision; + private int minorDivision; + private boolean showMajorNumbers; + private boolean showMinorNumbers; + private Font font; + private float charWidth, charHeight, descent; + + public RulerSkin() { + // For now the default colors are not from the Theme. + setColor(Color.BLACK); + setBackgroundColor(CSSColor.LightYellow.getColor()); + + markerSpacing = 5; + markerInsets = new Insets(0); + flip = false; + borders = Borders.ALL; + majorDivision = 4; + minorDivision = 2; + showMajorNumbers = false; + showMinorNumbers = false; + + Theme theme = currentTheme(); + setFont(theme.getFont()); + } + + @Override + public void install(Component component) { + super.install(component); + + Ruler ruler = (Ruler) component; + ruler.getRulerListeners().add(this); + } + + @Override + public void layout() { + // No-op + } + + @Override + public int getPreferredHeight(int width) { + Ruler ruler = (Ruler) getComponent(); + Orientation orientation = ruler.getOrientation(); + + // Give a little extra height if showing numbers + return (orientation == Orientation.HORIZONTAL) + ? ((showMajorNumbers || showMinorNumbers) + ? ((int) Math.ceil(charHeight) + MAJOR_SIZE + 5) : MAJOR_SIZE * 2) : 0; + } + + @Override + public int getPreferredWidth(int height) { + Ruler ruler = (Ruler) getComponent(); + Orientation orientation = ruler.getOrientation(); + + // Give a little extra width if showing numbers + return (orientation == Orientation.VERTICAL) + ? ((showMajorNumbers || showMinorNumbers) + ? ((int) Math.ceil(charWidth) + MAJOR_SIZE + 5) : MAJOR_SIZE * 2) : 0; + } + + private void showNumber(Graphics2D graphics, FontRenderContext fontRenderContext, int number, + int x, int y) { + String num = Integer.toString(number); + + StringCharacterIterator line; + GlyphVector glyphVector; + Rectangle2D textBounds; + float width, height; + float fx, fy; + + Ruler ruler = (Ruler) getComponent(); + Orientation orientation = ruler.getOrientation(); + + switch (orientation) { + case HORIZONTAL: + // Draw the whole number just off the tip of the line given by (x,y) + line = new StringCharacterIterator(num); + glyphVector = font.createGlyphVector(fontRenderContext, line); + textBounds = glyphVector.getLogicalBounds(); + width = (float) textBounds.getWidth(); + height = (float) textBounds.getHeight(); + fx = (float) x - (width / 2.0f); + if (flip) { + fy = (float) (y - 2); + } else { + fy = (float) (y - 1) + height; + } + graphics.drawGlyphVector(glyphVector, fx, fy); + break; + case VERTICAL: + // Draw the number one digit at a time, vertically just off the tip of the line + if (flip) { + fx = (float) (x - 1) - charWidth; + } else { + fx = (float) (x + 3); + } + int numDigits = num.length(); + float heightAdjust = (numDigits % 2 == 1) ? charHeight / 2.0f : 0.0f; + for (int i = 0; i < numDigits; i++) { + line = new StringCharacterIterator(num.substring(i, i + 1)); + glyphVector = font.createGlyphVector(fontRenderContext, line); + int midDigit = (numDigits + 1) / 2; + if (i <= midDigit) { + fy = (float) y + heightAdjust - descent - (float) (midDigit - i - 1) * charHeight; + } else { + fy = (float) y + heightAdjust - descent + (float) (i - midDigit - 1) * charHeight; + } + graphics.drawGlyphVector(glyphVector, fx, fy); + } + break; + default: + break; + } + } + + @Override + public void paint(Graphics2D graphics) { + int width = getWidth(); + int height = getHeight(); + + int top = markerInsets.top; + int left = markerInsets.left; + int bottom = height - markerInsets.bottom; + int right = width - markerInsets.right; + + Ruler ruler = (Ruler) getComponent(); + + graphics.setColor(backgroundColor); + graphics.fillRect(0, 0, width, height); + + graphics.setColor(color); + GraphicsUtilities.drawBorders(graphics, borders, 0, 0, height - 1, width - 1); + + height -= markerInsets.getHeight(); + width -= markerInsets.getWidth(); + + FontRenderContext fontRenderContext = showMajorNumbers || showMinorNumbers + ? GraphicsUtilities.prepareForText(graphics, font, color) : null; + + int start, end2, end3, end4; + + Orientation orientation = ruler.getOrientation(); + switch (orientation) { + case HORIZONTAL: + start = flip ? bottom - 1 : top; + end2 = flip ? (start - (MAJOR_SIZE - 1)) : (MAJOR_SIZE - 1); + end3 = flip ? (start - (MINOR_SIZE - 1)) : (MINOR_SIZE - 1); + end4 = flip ? (start - (REGULAR_SIZE - 1)) : (REGULAR_SIZE - 1); + + for (int i = 0, n = right / markerSpacing + 1; i < n; i++) { + int x = i * markerSpacing + left; + + if (majorDivision != 0 && i % majorDivision == 0) { + graphics.drawLine(x, start, x, end2); + // Don't show any numbers at 0 -- make a style for this? + if (showMajorNumbers && i > 0) { + showNumber(graphics, fontRenderContext, i, x, end2); + } + } else if (minorDivision != 0 && i % minorDivision == 0) { + graphics.drawLine(x, start, x, end3); + if (showMinorNumbers && i > 0) { + // Show the minor numbers at the same y point as the major + showNumber(graphics, fontRenderContext, i, x, end2); + } + } else { + graphics.drawLine(x, start, x, end4); + } + } + break; + + case VERTICAL: + start = flip ? right - 1 : left; + end2 = flip ? (start - (MAJOR_SIZE - 1)) : (MAJOR_SIZE - 1); + end3 = flip ? (start - (MINOR_SIZE - 1)) : (MINOR_SIZE - 1); + end4 = flip ? (start - (REGULAR_SIZE - 1)) : (REGULAR_SIZE - 1); + + for (int i = 0, n = bottom / markerSpacing + 1; i < n; i++) { + int y = i * markerSpacing + top; + + if (majorDivision != 0 && i % majorDivision == 0) { + graphics.drawLine(start, y, end2, y); + // Don't show any numbers at 0 -- make a style for this? + if (showMajorNumbers && i > 0) { + showNumber(graphics, fontRenderContext, i, end2, y); + } + } else if (minorDivision != 0 && i % minorDivision == 0) { + graphics.drawLine(start, y, end3, y); + if (showMinorNumbers && i > 0) { + showNumber(graphics, fontRenderContext, i, end3, y); + } + } else { + graphics.drawLine(start, y, end4, y); + } + } + break; + + default: + break; + } + } + + @Override + public void orientationChanged(Ruler ruler) { + invalidateComponent(); + } + + /** + * @return The interval at which the "major" (that is, the long) + * markers are drawn. + */ + public final int getMajorDivision() { + return majorDivision; + } + + /** + * Set the major division interval. + * + * @param major The number of markers interval at which to draw + * a "major" (long) marker. Can be zero to not draw any major + * markers. + */ + public final void setMajorDivision(int major) { + Utils.checkNonNegative(major, "majorDivision"); + + // TODO: check for sanity of major vs. minor here?? + this.majorDivision = major; + repaintComponent(); + } + + public final void setMajorDivision(Number major) { + Utils.checkNull(major, "majorDivision"); + + setMajorDivision(major.intValue()); + } + + /** + * @return The interval at which the "minor" (that is, the slightly + * longer than normal) markers are drawn. + */ + public final int getMinorDivision() { + return minorDivision; + } + + /** + * Set the minor division interval. + * + * @param minor The number of markers interval at which to draw + * a "minor" (slightly longer than normal) marker. Can be zero + * to not draw any minor markers. + */ + public final void setMinorDivision(int minor) { + Utils.checkNonNegative(minor, "minorDivision"); + + // TODO: check for sanity of major vs. minor here?? + this.minorDivision = minor; + repaintComponent(); + } + + public final void setMinorDivision(Number minor) { + Utils.checkNull(minor, "minorDivision"); + + setMinorDivision(minor.intValue()); + } + + /** + * @return The number of pixels interval at which to draw markers. + */ + public final int getMarkerSpacing() { + return markerSpacing; + } + + /** + * Set the number of pixels interval at which to draw the markers. + * + * @param spacing The number of pixels between markers (must be {@code >= 1}). + */ + public final void setMarkerSpacing(int spacing) { + Utils.checkPositive(spacing, "markerSpacing"); + + this.markerSpacing = spacing; + invalidateComponent(); + } + + public final void setMarkerSpacing(Number spacing) { + Utils.checkNull(spacing, "markerSpacing"); + + setMarkerSpacing(spacing.intValue()); + } + + /** + * @return Whether the ruler is "flipped", that is the markers + * start from the inside rather than the outside. + */ + public final boolean getFlip() { + return flip; + } + + public final void setFlip(boolean flip) { + this.flip = flip; + } + + /** + * @return Whether to display numbers at each major division. + */ + public final boolean getShowMajorNumbers() { + return showMajorNumbers; + } + + /** + * Sets the flag to say whether to show numbers at each major division. + * + * @param showMajorNumbers Whether numbers should be shown for major divisions. + */ + public final void setShowMajorNumbers(boolean showMajorNumbers) { + this.showMajorNumbers = showMajorNumbers; + invalidateComponent(); + } + + /** + * @return Whether to display numbers at each minor division. + */ + public final boolean getShowMinorNumbers() { + return showMinorNumbers; + } + + /** + * Sets the flag to say whether to show numbers at each minor division. + * + * @param showMinorNumbers Whether numbers should be shown for minor divisions. + */ + public final void setShowMinorNumbers(boolean showMinorNumbers) { + this.showMinorNumbers = showMinorNumbers; + invalidateComponent(); + } + + /** + * @return The border configuration for this ruler. + */ + public final Borders getBorders() { + return borders; + } + + public final void setBorders(Borders borders) { + Utils.checkNull(borders, "borders"); + + this.borders = borders; + repaintComponent(); + } + + /** + * @return The insets for the markers (on each edge). + */ + public final Insets getMarkerInsets() { + return markerInsets; + } + + public final void setMarkerInsets(Insets insets) { + Utils.checkNull(insets, "markerInsets"); + + this.markerInsets = insets; + repaintComponent(); + } + + public final void setMarkerInsets(Dictionary<String, ?> insets) { + setMarkerInsets(new Insets(insets)); + } + + public final void setMarkerInsets(Sequence<?> insets) { + setMarkerInsets(new Insets(insets)); + } + + public final void setMarkerInsets(int insets) { + setMarkerInsets(new Insets(insets)); + } + + public final void setMarkerInsets(Number insets) { + setMarkerInsets(new Insets(insets)); + } + + public final void setMarkerInsets(String insets) { + setMarkerInsets(Insets.decode(insets)); + } + + /** + * Returns the foreground color for the markers of the ruler. + * + * @return The foreground (marker) color. + */ + public final Color getColor() { + return color; + } + + /** + * Sets the foreground color for the markers of the ruler. + * + * @param color The foreground (that is, the marker) color. + */ + public final void setColor(Color color) { + Utils.checkNull(color, "color"); + + this.color = color; + repaintComponent(); + } + + /** + * Sets the foreground color for the markers of the ruler. + * + * @param color Any of the {@linkplain GraphicsUtilities#decodeColor color + * values recognized by Pivot}. + */ + public final void setColor(String color) { + setColor(GraphicsUtilities.decodeColor(color, "color")); + } + + public final void setColor(int color) { + Theme theme = currentTheme(); + setColor(theme.getColor(color)); + } + + /** + * Returns the background color of the ruler. + * + * @return The current background color. + */ + public final Color getBackgroundColor() { + return backgroundColor; + } + + /** + * Sets the background color of the ruler. + * + * @param backgroundColor New background color value (can be {@code null} + * for a transparent background). + */ + public final void setBackgroundColor(Color backgroundColor) { + this.backgroundColor = backgroundColor; + repaintComponent(); + } + + /** + * Sets the background color of the ruler. + * + * @param backgroundColor Any of the + * {@linkplain GraphicsUtilities#decodeColor color values recognized by + * Pivot}. + */ + public final void setBackgroundColor(String backgroundColor) { + setBackgroundColor(GraphicsUtilities.decodeColor(backgroundColor, "backgroundColor")); + } + + public final void setBackgroundColor(int backgroundColor) { + Theme theme = currentTheme(); + setBackgroundColor(theme.getColor(backgroundColor)); + } + + /** + * @return The font used to format division numbers (if enabled). + */ + public final Font getFont() { + return font; + } + + /** + * Sets the font used in rendering the Ruler's text. + * + * @param font The new font to use. + */ + public final void setFont(Font font) { + Utils.checkNull(font, "font"); + + // The font we will use is the same name and style, but a 11 pt type + this.font = font.deriveFont(11.0f); + + // Make some size calculations for the drawing code + FontRenderContext fontRenderContext = Platform.getFontRenderContext(); + GlyphVector glyphVector = this.font.createGlyphVector(fontRenderContext, "0"); + Rectangle2D textBounds = glyphVector.getLogicalBounds(); + this.charWidth = (float) textBounds.getWidth(); + // Since we're just drawing numbers, the line spacing can be just the ascent value for the font + LineMetrics lm = this.font.getLineMetrics("0", fontRenderContext); + this.charHeight = lm.getAscent(); + this.descent = lm.getDescent(); + + invalidateComponent(); + } + + /** + * Sets the font used in rendering the Ruler's text. + * + * @param font A {@link ComponentSkin#decodeFont(String) font specification} + */ + public final void setFont(String font) { + setFont(decodeFont(font)); + } + + /** + * Sets the font used in rendering the Ruler's text. + * + * @param font A dictionary {@link Theme#deriveFont describing a font} + */ + public final void setFont(Dictionary<String, ?> font) { + setFont(Theme.deriveFont(font)); + } + +}
Propchange: pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/RulerSkin.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TabPaneSkin.java URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TabPaneSkin.java?rev=1913470&r1=1913469&r2=1913470&view=diff ============================================================================== --- pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TabPaneSkin.java (original) +++ pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TabPaneSkin.java Tue Oct 31 19:15:47 2023 @@ -1,41 +1,41 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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 org.apache.pivot.wtk.skin; - -import org.apache.pivot.wtk.BoxPane; -import org.apache.pivot.wtk.TabPane; - -/** - * Tab pane skin. Note that this class is abstract but only because in layout - * method there are many things already defined that uses the original skin - * implementation (TerraTabPaneSkin). - */ -public abstract class TabPaneSkin extends ContainerSkin implements TabPane.Skin { - - protected BoxPane buttonBoxPane = new BoxPane(); - - @Override - public boolean isVisible(final int index) { - return buttonBoxPane.get(index).isVisible(); - } - - @Override - public void setVisible(final int index, final boolean value) { - buttonBoxPane.get(index).setVisible(value); - } - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you 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 org.apache.pivot.wtk.skin; + +import org.apache.pivot.wtk.BoxPane; +import org.apache.pivot.wtk.TabPane; + +/** + * Tab pane skin. Note that this class is abstract but only because in layout + * method there are many things already defined that uses the original skin + * implementation (TerraTabPaneSkin). + */ +public abstract class TabPaneSkin extends ContainerSkin implements TabPane.Skin { + + protected BoxPane buttonBoxPane = new BoxPane(); + + @Override + public boolean isVisible(final int index) { + return buttonBoxPane.get(index).isVisible(); + } + + @Override + public void setVisible(final int index, final boolean value) { + buttonBoxPane.get(index).setVisible(value); + } + +} Propchange: pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/TabPaneSkin.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/VFSBrowserSkin.java URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/VFSBrowserSkin.java?rev=1913470&r1=1913469&r2=1913470&view=diff ============================================================================== --- pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/VFSBrowserSkin.java (original) +++ pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/VFSBrowserSkin.java Tue Oct 31 19:15:47 2023 @@ -1,35 +1,35 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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 org.apache.pivot.wtk.skin; - -import org.apache.pivot.wtk.Component; -import org.apache.pivot.wtk.VFSBrowser; -import org.apache.pivot.wtk.VFSBrowserListener; - -/** - * Abstract base class for Commons VFS browser skins. - */ -public abstract class VFSBrowserSkin extends ContainerSkin implements VFSBrowser.Skin, - VFSBrowserListener { - @Override - public void install(final Component component) { - super.install(component); - - VFSBrowser fileBrowser = (VFSBrowser) component; - fileBrowser.getFileBrowserListeners().add(this); - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you 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 org.apache.pivot.wtk.skin; + +import org.apache.pivot.wtk.Component; +import org.apache.pivot.wtk.VFSBrowser; +import org.apache.pivot.wtk.VFSBrowserListener; + +/** + * Abstract base class for Commons VFS browser skins. + */ +public abstract class VFSBrowserSkin extends ContainerSkin implements VFSBrowser.Skin, + VFSBrowserListener { + @Override + public void install(final Component component) { + super.install(component); + + VFSBrowser fileBrowser = (VFSBrowser) component; + fileBrowser.getFileBrowserListeners().add(this); + } +} Propchange: pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/VFSBrowserSkin.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/util/ColorUtilities.java URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/util/ColorUtilities.java?rev=1913470&r1=1913469&r2=1913470&view=diff ============================================================================== --- pivot/trunk/wtk/src/org/apache/pivot/wtk/util/ColorUtilities.java (original) +++ pivot/trunk/wtk/src/org/apache/pivot/wtk/util/ColorUtilities.java Tue Oct 31 19:15:47 2023 @@ -1,299 +1,299 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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 org.apache.pivot.wtk.util; - -import java.awt.Color; - -import org.apache.pivot.util.Utils; -import org.apache.pivot.wtk.Theme; -import org.apache.pivot.wtk.CSSColor; -import org.apache.pivot.wtk.GraphicsUtilities; - - -/** - * Utility methods for/on Colors. - */ -public final class ColorUtilities { - - /** - * Private constructor since this is a utility class (all static methods). - */ - private ColorUtilities() { - } - - /** - * Returns a brighter version of the specified color. Specifically, it - * increases the brightness (in the HSB color model) by the given - * {@code adjustment} factor (usually in the range ]0 .. 1[). - * - * @param color the color - * @param adjustment the adjustment factor - * @return the color brightened - */ - public static Color brighten(final Color color, final float adjustment) { - return adjustBrightness(color, adjustment); - } - - /** - * Returns a darker version of the specified color. Specifically, it - * decreases the brightness (in the HSB color model) by the given - * {@code adjustment} factor (usually in the range ]0 .. 1[). - * - * @param color the color - * @param adjustment the adjustment factor - * @return the color darkened - */ - public static Color darken(final Color color, final float adjustment) { - return adjustBrightness(color, (adjustment * -1.0f)); - } - - /** - * Change the brightness of the given color, and returns the changed color. - * - * @param color the color - * @param adjustment the adjustment factor (usually in the range ]0 .. 1[) - * @return the new color - */ - public static Color adjustBrightness(final Color color, final 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), true); - } - - /** - * Returns a numeric version of the difference of all color RGB components. - * - * @param color1 the first color - * @param color2 the second color - * @return the value of the difference - */ - public static int colorDifferenceRGBTotal(final Color color1, final Color color2) { - return Math.abs(color1.getRed() - color2.getRed()) - + Math.abs(color1.getGreen() - color2.getGreen()) - + Math.abs(color1.getBlue() - color2.getBlue()); - } - - /** - * Returns a numeric version of the difference of all color RGB components. - * - * @param color1 the first color - * @param color2 the second color - * @return an array of three elements, containing a value of the difference - * for any channel (red, green, blue), with values in the usual RGB range - */ - public static int[] colorDifferenceRGB(final Color color1, final Color color2) { - int[] difference = new int[3]; - - difference[0] = Math.abs(color1.getRed() - color2.getRed()); - difference[1] = Math.abs(color1.getGreen() - color2.getGreen()); - difference[2] = Math.abs(color1.getBlue() - color2.getBlue()); - - return difference; - } - - /** - * Returns a Color by subtracting the given color from white. - * - * @param color the color to subtract - * @return a Color - */ - public static Color colorDifferenceFromWhite(final Color color) { - int[] difference = new int[3]; - - difference[0] = 255 - color.getRed(); - difference[1] = 255 - color.getGreen(); - difference[2] = 255 - color.getBlue(); - - return new Color(difference[0], difference[1], difference[2]); - } - - /** - * Returns a numeric version of the difference of all color in HSV - * components. - * - * @param color1 the first color - * @param color2 the second color - * @return an array of three elements, containing a value of the difference - * for any channel (hue, saturation, brightness), with values in the usual - * HSV range - */ - public static float[] colorDifferenceHSV(final Color color1, final Color color2) { - float[] difference = new float[3]; - - float[] hsb1 = Color.RGBtoHSB(color1.getRed(), color1.getGreen(), color1.getBlue(), null); - float[] hsb2 = Color.RGBtoHSB(color2.getRed(), color2.getGreen(), color2.getBlue(), null); - - difference[0] = Math.abs(hsb1[0] - hsb2[0]); - difference[1] = Math.abs(hsb1[1] - hsb2[1]); - difference[2] = Math.abs(hsb1[2] - hsb2[2]); - - return difference; - } - - /** - * @return A solid color from the given color value (that is, with the transparency removed - * from the original). - * @param original The original (potentially transparent) color. - */ - public static Color toSolidColor(final Color original) { - return new Color(original.getRed(), original.getGreen(), original.getBlue()); - } - - /** - * Returns a modified version of the given Color. - * @param original The original color - * @param transparency The desired transparency (alpha) to set. - * @return An updated version of the color, with the given transparency. - */ - public static Color toTransparentColor(final Color original, final int transparency) { - return new Color(original.getRed(), original.getGreen(), original.getBlue(), transparency); - } - - /** - * Returns a modified version of the given Theme color. - * @param colorIndex Index into the Theme color palette of the color to modify. - * @param transparency The transparency value to set in the color. - * @return An updated version of the color, with the given transparency. - */ - public static Color toTransparentColor(final int colorIndex, final int transparency) { - Theme theme = Theme.getTheme(); - return toTransparentColor(theme.getColor(colorIndex), transparency); - } - - /** - * Returns a modified version of the given {@link CSSColor}. - * @param original The original color. - * @param transparency The desired transparency (alpha) to set. - * @return An color value updated from the original with the given transparency. - */ - public static Color toTransparentColor(final CSSColor original, final int transparency) { - return toTransparentColor(original.getColor(), transparency); - } - - /** - * Returns a modified version of the given Color. - * <p> Deprecated in favor of new {@link #toTransparentColor(Color,int)} method (same functionality, nicer name). - * @param original The original color - * @param transparency The desired transparency (alpha) to set. - * @return An updated version of the color, with the given transparency. - */ - @Deprecated - public static Color setTransparencyInColor(final Color original, final int transparency) { - return toTransparentColor(original, transparency); - } - - /** - * Returns a modified version of the given Theme color. - * <p> Deprecated in favor of new {@link #toTransparentColor(int,int)} method (same functionality, nicer name). - * @param colorIndex Index into the Theme color palette of the color to modify. - * @param transparency The transparency value to set in the color. - * @return An updated version of the color, with the given transparency. - */ - @Deprecated - public static Color setTransparencyInColor(final int colorIndex, final int transparency) { - return toTransparentColor(colorIndex, transparency); - } - - /** - * Returns a modified version of the given {@link CSSColor}. - * <p> Deprecated in favor of new {@link #toTransparentColor(CSSColor,int)} method (same functionality, nicer name). - * @param original The original color. - * @param transparency The desired transparency (alpha) to set. - * @return An color value updated from the original with the given transparency. - */ - @Deprecated - public static Color setTransparencyInColor(final CSSColor original, final int transparency) { - return toTransparentColor(original, transparency); - } - - /** - * @return An encoded value for the given color in the form of: - * <code>#RRGGBB</code> or <code>0xRRGGBBTT</code> (where <code>"TT"</code> is the - * alpha transparency value of the color, if not solid), - * either of which is suitable for lookup in the - * {@link org.apache.pivot.wtk.GraphicsUtilities#decodeColor(String)} method. - * @param color The input color to convert. - */ - public static String toStringValue(final Color color) { - int alpha = color.getAlpha(); - if (alpha != 255) { - // A translucent color - return String.format("0x%02X%02X%02X%02X", - color.getRed(), color.getGreen(), color.getBlue(), alpha); - } else { - // A solid color - return String.format("#%02X%02X%02X", - color.getRed(), color.getGreen(), color.getBlue()); - } - } - - /** - * @return An encoded value for the given {@link CSSColor} in the form of: - * <code>#RRGGBB</code> only (since these are always solid colors by definition), - * which is suitable for lookup in the - * {@link org.apache.pivot.wtk.GraphicsUtilities#decodeColor(String)} method. - * @param color The input color to convert. - * @see #toStringValue(Color) - */ - public static String toStringValue(final CSSColor color) { - return toStringValue(color.getColor()); - } - - /** - * Interpret an object as a color value. - * - * @param colorValue One of a {@link String} (interpreted by {@link GraphicsUtilities#decodeColor(String,String)}), - * a straight {@link Color}, one of our {@link CSSColor} values, or an integer index into the theme's - * color palette. - * @param description An optional description for the call to {@link Utils#checkNull} in case of a null input value. - * @param allowNull Whether or not to allow a null color. - * @return The real {@link Color} value. - * @throws IllegalArgumentException if the {@code colorValue} is {@code null} (unless {@code allowNull} - * is {@code true}), or of a type we don't recognize. - */ - public static Color fromObject(final Object colorValue, final String description, final boolean allowNull) { - if (!allowNull) { - Utils.checkNull(colorValue, description); - } - - Color color; - - if (allowNull && colorValue == null) { - color = null; - } else if (colorValue instanceof Color) { - color = (Color) colorValue; - } else if (colorValue instanceof String) { - Color decodedColor = GraphicsUtilities.decodeColor((String) colorValue); - if (!allowNull) { - Utils.checkNull(decodedColor, description); - } - color = decodedColor; - } else if (colorValue instanceof CSSColor) { - color = ((CSSColor) colorValue).getColor(); - } else if (colorValue instanceof Number) { - Theme theme = Theme.getTheme(); - color = theme.getColor(((Number) colorValue).intValue()); - } else { - throw new IllegalArgumentException("Object of type " - + colorValue.getClass().getName() + " cannot be converted to a Color."); - } - - return color; - } - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you 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 org.apache.pivot.wtk.util; + +import java.awt.Color; + +import org.apache.pivot.util.Utils; +import org.apache.pivot.wtk.Theme; +import org.apache.pivot.wtk.CSSColor; +import org.apache.pivot.wtk.GraphicsUtilities; + + +/** + * Utility methods for/on Colors. + */ +public final class ColorUtilities { + + /** + * Private constructor since this is a utility class (all static methods). + */ + private ColorUtilities() { + } + + /** + * Returns a brighter version of the specified color. Specifically, it + * increases the brightness (in the HSB color model) by the given + * {@code adjustment} factor (usually in the range ]0 .. 1[). + * + * @param color the color + * @param adjustment the adjustment factor + * @return the color brightened + */ + public static Color brighten(final Color color, final float adjustment) { + return adjustBrightness(color, adjustment); + } + + /** + * Returns a darker version of the specified color. Specifically, it + * decreases the brightness (in the HSB color model) by the given + * {@code adjustment} factor (usually in the range ]0 .. 1[). + * + * @param color the color + * @param adjustment the adjustment factor + * @return the color darkened + */ + public static Color darken(final Color color, final float adjustment) { + return adjustBrightness(color, (adjustment * -1.0f)); + } + + /** + * Change the brightness of the given color, and returns the changed color. + * + * @param color the color + * @param adjustment the adjustment factor (usually in the range ]0 .. 1[) + * @return the new color + */ + public static Color adjustBrightness(final Color color, final 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), true); + } + + /** + * Returns a numeric version of the difference of all color RGB components. + * + * @param color1 the first color + * @param color2 the second color + * @return the value of the difference + */ + public static int colorDifferenceRGBTotal(final Color color1, final Color color2) { + return Math.abs(color1.getRed() - color2.getRed()) + + Math.abs(color1.getGreen() - color2.getGreen()) + + Math.abs(color1.getBlue() - color2.getBlue()); + } + + /** + * Returns a numeric version of the difference of all color RGB components. + * + * @param color1 the first color + * @param color2 the second color + * @return an array of three elements, containing a value of the difference + * for any channel (red, green, blue), with values in the usual RGB range + */ + public static int[] colorDifferenceRGB(final Color color1, final Color color2) { + int[] difference = new int[3]; + + difference[0] = Math.abs(color1.getRed() - color2.getRed()); + difference[1] = Math.abs(color1.getGreen() - color2.getGreen()); + difference[2] = Math.abs(color1.getBlue() - color2.getBlue()); + + return difference; + } + + /** + * Returns a Color by subtracting the given color from white. + * + * @param color the color to subtract + * @return a Color + */ + public static Color colorDifferenceFromWhite(final Color color) { + int[] difference = new int[3]; + + difference[0] = 255 - color.getRed(); + difference[1] = 255 - color.getGreen(); + difference[2] = 255 - color.getBlue(); + + return new Color(difference[0], difference[1], difference[2]); + } + + /** + * Returns a numeric version of the difference of all color in HSV + * components. + * + * @param color1 the first color + * @param color2 the second color + * @return an array of three elements, containing a value of the difference + * for any channel (hue, saturation, brightness), with values in the usual + * HSV range + */ + public static float[] colorDifferenceHSV(final Color color1, final Color color2) { + float[] difference = new float[3]; + + float[] hsb1 = Color.RGBtoHSB(color1.getRed(), color1.getGreen(), color1.getBlue(), null); + float[] hsb2 = Color.RGBtoHSB(color2.getRed(), color2.getGreen(), color2.getBlue(), null); + + difference[0] = Math.abs(hsb1[0] - hsb2[0]); + difference[1] = Math.abs(hsb1[1] - hsb2[1]); + difference[2] = Math.abs(hsb1[2] - hsb2[2]); + + return difference; + } + + /** + * @return A solid color from the given color value (that is, with the transparency removed + * from the original). + * @param original The original (potentially transparent) color. + */ + public static Color toSolidColor(final Color original) { + return new Color(original.getRed(), original.getGreen(), original.getBlue()); + } + + /** + * Returns a modified version of the given Color. + * @param original The original color + * @param transparency The desired transparency (alpha) to set. + * @return An updated version of the color, with the given transparency. + */ + public static Color toTransparentColor(final Color original, final int transparency) { + return new Color(original.getRed(), original.getGreen(), original.getBlue(), transparency); + } + + /** + * Returns a modified version of the given Theme color. + * @param colorIndex Index into the Theme color palette of the color to modify. + * @param transparency The transparency value to set in the color. + * @return An updated version of the color, with the given transparency. + */ + public static Color toTransparentColor(final int colorIndex, final int transparency) { + Theme theme = Theme.getTheme(); + return toTransparentColor(theme.getColor(colorIndex), transparency); + } + + /** + * Returns a modified version of the given {@link CSSColor}. + * @param original The original color. + * @param transparency The desired transparency (alpha) to set. + * @return An color value updated from the original with the given transparency. + */ + public static Color toTransparentColor(final CSSColor original, final int transparency) { + return toTransparentColor(original.getColor(), transparency); + } + + /** + * Returns a modified version of the given Color. + * <p> Deprecated in favor of new {@link #toTransparentColor(Color,int)} method (same functionality, nicer name). + * @param original The original color + * @param transparency The desired transparency (alpha) to set. + * @return An updated version of the color, with the given transparency. + */ + @Deprecated + public static Color setTransparencyInColor(final Color original, final int transparency) { + return toTransparentColor(original, transparency); + } + + /** + * Returns a modified version of the given Theme color. + * <p> Deprecated in favor of new {@link #toTransparentColor(int,int)} method (same functionality, nicer name). + * @param colorIndex Index into the Theme color palette of the color to modify. + * @param transparency The transparency value to set in the color. + * @return An updated version of the color, with the given transparency. + */ + @Deprecated + public static Color setTransparencyInColor(final int colorIndex, final int transparency) { + return toTransparentColor(colorIndex, transparency); + } + + /** + * Returns a modified version of the given {@link CSSColor}. + * <p> Deprecated in favor of new {@link #toTransparentColor(CSSColor,int)} method (same functionality, nicer name). + * @param original The original color. + * @param transparency The desired transparency (alpha) to set. + * @return An color value updated from the original with the given transparency. + */ + @Deprecated + public static Color setTransparencyInColor(final CSSColor original, final int transparency) { + return toTransparentColor(original, transparency); + } + + /** + * @return An encoded value for the given color in the form of: + * <code>#RRGGBB</code> or <code>0xRRGGBBTT</code> (where <code>"TT"</code> is the + * alpha transparency value of the color, if not solid), + * either of which is suitable for lookup in the + * {@link org.apache.pivot.wtk.GraphicsUtilities#decodeColor(String)} method. + * @param color The input color to convert. + */ + public static String toStringValue(final Color color) { + int alpha = color.getAlpha(); + if (alpha != 255) { + // A translucent color + return String.format("0x%02X%02X%02X%02X", + color.getRed(), color.getGreen(), color.getBlue(), alpha); + } else { + // A solid color + return String.format("#%02X%02X%02X", + color.getRed(), color.getGreen(), color.getBlue()); + } + } + + /** + * @return An encoded value for the given {@link CSSColor} in the form of: + * <code>#RRGGBB</code> only (since these are always solid colors by definition), + * which is suitable for lookup in the + * {@link org.apache.pivot.wtk.GraphicsUtilities#decodeColor(String)} method. + * @param color The input color to convert. + * @see #toStringValue(Color) + */ + public static String toStringValue(final CSSColor color) { + return toStringValue(color.getColor()); + } + + /** + * Interpret an object as a color value. + * + * @param colorValue One of a {@link String} (interpreted by {@link GraphicsUtilities#decodeColor(String,String)}), + * a straight {@link Color}, one of our {@link CSSColor} values, or an integer index into the theme's + * color palette. + * @param description An optional description for the call to {@link Utils#checkNull} in case of a null input value. + * @param allowNull Whether or not to allow a null color. + * @return The real {@link Color} value. + * @throws IllegalArgumentException if the {@code colorValue} is {@code null} (unless {@code allowNull} + * is {@code true}), or of a type we don't recognize. + */ + public static Color fromObject(final Object colorValue, final String description, final boolean allowNull) { + if (!allowNull) { + Utils.checkNull(colorValue, description); + } + + Color color; + + if (allowNull && colorValue == null) { + color = null; + } else if (colorValue instanceof Color) { + color = (Color) colorValue; + } else if (colorValue instanceof String) { + Color decodedColor = GraphicsUtilities.decodeColor((String) colorValue); + if (!allowNull) { + Utils.checkNull(decodedColor, description); + } + color = decodedColor; + } else if (colorValue instanceof CSSColor) { + color = ((CSSColor) colorValue).getColor(); + } else if (colorValue instanceof Number) { + Theme theme = Theme.getTheme(); + color = theme.getColor(((Number) colorValue).intValue()); + } else { + throw new IllegalArgumentException("Object of type " + + colorValue.getClass().getName() + " cannot be converted to a Color."); + } + + return color; + } + +} Propchange: pivot/trunk/wtk/src/org/apache/pivot/wtk/util/ColorUtilities.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/util/TextAreaOutputStream.java URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/util/TextAreaOutputStream.java?rev=1913470&r1=1913469&r2=1913470&view=diff ============================================================================== --- pivot/trunk/wtk/src/org/apache/pivot/wtk/util/TextAreaOutputStream.java (original) +++ pivot/trunk/wtk/src/org/apache/pivot/wtk/util/TextAreaOutputStream.java Tue Oct 31 19:15:47 2023 @@ -1,187 +1,187 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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 org.apache.pivot.wtk.util; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import org.apache.pivot.wtk.ApplicationContext; -import org.apache.pivot.wtk.Bounds; -import org.apache.pivot.wtk.TextArea; - -/** - * Creates an {@link OutputStream} that outputs to a {@link TextArea} - * (in the EDT thread, using callbacks) for display. - * <p> Can be used with the {@link org.apache.pivot.util.Console} class for output (using the - * {@link #toPrintStream} method). - */ -public final class TextAreaOutputStream extends OutputStream { - /** The TextArea we are going to stream to. */ - private TextArea textArea; - - /** Default line buffer size (can be overridden through a constructor). */ - private static final int DEFAULT_BUFFER_SIZE = 2_048; - - /** Buffer size to use for incoming lines of text. */ - private int lineBufferSize; - - /** The charset to use for converting incoming bytes to characters. */ - private Charset incomingCharset; - - /** The buffered line for this stream. */ - private ByteArrayOutputStream lineBuffer; - - /** - * Simple constructor given the {@link TextArea} to stream to; uses the system - * default charset for conversion, and the default buffer size. - * - * @param textAreaToUse The TextArea to use for output. - */ - public TextAreaOutputStream(final TextArea textAreaToUse) { - this(textAreaToUse, null, DEFAULT_BUFFER_SIZE); - } - - /** - * Constructor given the {@link TextArea} to stream to, and the - * non-default line buffer size to use; uses the system default charset. - * - * @param textAreaToUse The TextArea to use for output. - * @param lineBufferSizeToUse The non-default size for the input line buffer. - */ - public TextAreaOutputStream(final TextArea textAreaToUse, final int lineBufferSizeToUse) { - this(textAreaToUse, null, lineBufferSizeToUse); - } - - /** - * Constructor given the {@link TextArea} to stream to, and the charset to use - * for decoding the incoming bytes into characters; uses the default line buffer size. - * - * @param textAreaToUse The TextArea to use for output. - * @param charsetToUse The charset used to convert incoming bytes to characters - * (can be {@code null} to use the platform standard charset). - */ - public TextAreaOutputStream(final TextArea textAreaToUse, final Charset charsetToUse) { - this(textAreaToUse, charsetToUse, DEFAULT_BUFFER_SIZE); - } - - /** - * Constructor given the {@link TextArea} to stream to, the charset to use - * for decoding the incoming bytes into characters, and the line buffer size to use. - * - * @param textAreaToUse The TextArea to use for output. - * @param charsetToUse The charset used to convert incoming bytes to characters - * (can be {@code null} to use the platform standard charset). - * @param lineBufferSizeToUse The size for the input line buffer. - */ - public TextAreaOutputStream(final TextArea textAreaToUse, final Charset charsetToUse, - final int lineBufferSizeToUse) { - textArea = textAreaToUse; - incomingCharset = (charsetToUse == null) ? Charset.defaultCharset() : charsetToUse; - lineBufferSize = lineBufferSizeToUse; - lineBuffer = new ByteArrayOutputStream(lineBufferSize); - } - - /** - * @throws IOException if this stream is already closed. - */ - private void checkIfOpen() throws IOException { - if (textArea == null || lineBuffer == null) { - throw new IOException("TextAreaOutputStream is closed."); - } - } - - /** - * Flush the (byte) line buffer if there is anything cached. - * @param addNewLine Add a newline ('\n') character after any buffered text. - */ - private void flushLineBuffer(final boolean addNewLine) { - final String text; - - if (lineBuffer.size() > 0) { - byte[] bytes = lineBuffer.toByteArray(); - text = new String(bytes, incomingCharset); - lineBuffer.reset(); - } else { - text = ""; - } - - // Do the actual text manipulation (including scrolling) on the event thread - if (!text.isEmpty() || addNewLine) { - ApplicationContext.queueCallback(() -> { - int length = textArea.getCharacterCount(); - int newLength = length; - - if (!text.isEmpty()) { - textArea.insertText(text, length); - newLength += text.length(); - } - - if (addNewLine) { - textArea.insertText("\n", newLength++); - } - - final int lastCharPos = newLength; - - // In order to allow time for the skin to render the latest additions, - // queue the actual scrolling until that is done - ApplicationContext.queueCallback(() -> { - Bounds lastCharBounds = textArea.getCharacterBounds(lastCharPos); - textArea.scrollAreaToVisible(lastCharBounds); - }); - }); - } - } - - @Override - public void close() throws IOException { - flush(); - textArea = null; - incomingCharset = null; - lineBuffer = null; - } - - @Override - public void flush() throws IOException { - checkIfOpen(); - flushLineBuffer(false); - } - - @Override - public void write(final int b) throws IOException { - if (b == '\n') { - flushLineBuffer(true); - } else if (b != '\r') { - lineBuffer.write(b); - } - } - - /** - * @return A new {@link PrintStream} using this object as the basis (and the - * same charset specified by one of the constructors). - */ - public PrintStream toPrintStream() { - try { - return new PrintStream(this, false, incomingCharset.name()); - } catch (UnsupportedEncodingException uee) { - throw new RuntimeException("Impossible unsupported encoding error!", uee); - } - } - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you 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 org.apache.pivot.wtk.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import org.apache.pivot.wtk.ApplicationContext; +import org.apache.pivot.wtk.Bounds; +import org.apache.pivot.wtk.TextArea; + +/** + * Creates an {@link OutputStream} that outputs to a {@link TextArea} + * (in the EDT thread, using callbacks) for display. + * <p> Can be used with the {@link org.apache.pivot.util.Console} class for output (using the + * {@link #toPrintStream} method). + */ +public final class TextAreaOutputStream extends OutputStream { + /** The TextArea we are going to stream to. */ + private TextArea textArea; + + /** Default line buffer size (can be overridden through a constructor). */ + private static final int DEFAULT_BUFFER_SIZE = 2_048; + + /** Buffer size to use for incoming lines of text. */ + private int lineBufferSize; + + /** The charset to use for converting incoming bytes to characters. */ + private Charset incomingCharset; + + /** The buffered line for this stream. */ + private ByteArrayOutputStream lineBuffer; + + /** + * Simple constructor given the {@link TextArea} to stream to; uses the system + * default charset for conversion, and the default buffer size. + * + * @param textAreaToUse The TextArea to use for output. + */ + public TextAreaOutputStream(final TextArea textAreaToUse) { + this(textAreaToUse, null, DEFAULT_BUFFER_SIZE); + } + + /** + * Constructor given the {@link TextArea} to stream to, and the + * non-default line buffer size to use; uses the system default charset. + * + * @param textAreaToUse The TextArea to use for output. + * @param lineBufferSizeToUse The non-default size for the input line buffer. + */ + public TextAreaOutputStream(final TextArea textAreaToUse, final int lineBufferSizeToUse) { + this(textAreaToUse, null, lineBufferSizeToUse); + } + + /** + * Constructor given the {@link TextArea} to stream to, and the charset to use + * for decoding the incoming bytes into characters; uses the default line buffer size. + * + * @param textAreaToUse The TextArea to use for output. + * @param charsetToUse The charset used to convert incoming bytes to characters + * (can be {@code null} to use the platform standard charset). + */ + public TextAreaOutputStream(final TextArea textAreaToUse, final Charset charsetToUse) { + this(textAreaToUse, charsetToUse, DEFAULT_BUFFER_SIZE); + } + + /** + * Constructor given the {@link TextArea} to stream to, the charset to use + * for decoding the incoming bytes into characters, and the line buffer size to use. + * + * @param textAreaToUse The TextArea to use for output. + * @param charsetToUse The charset used to convert incoming bytes to characters + * (can be {@code null} to use the platform standard charset). + * @param lineBufferSizeToUse The size for the input line buffer. + */ + public TextAreaOutputStream(final TextArea textAreaToUse, final Charset charsetToUse, + final int lineBufferSizeToUse) { + textArea = textAreaToUse; + incomingCharset = (charsetToUse == null) ? Charset.defaultCharset() : charsetToUse; + lineBufferSize = lineBufferSizeToUse; + lineBuffer = new ByteArrayOutputStream(lineBufferSize); + } + + /** + * @throws IOException if this stream is already closed. + */ + private void checkIfOpen() throws IOException { + if (textArea == null || lineBuffer == null) { + throw new IOException("TextAreaOutputStream is closed."); + } + } + + /** + * Flush the (byte) line buffer if there is anything cached. + * @param addNewLine Add a newline ('\n') character after any buffered text. + */ + private void flushLineBuffer(final boolean addNewLine) { + final String text; + + if (lineBuffer.size() > 0) { + byte[] bytes = lineBuffer.toByteArray(); + text = new String(bytes, incomingCharset); + lineBuffer.reset(); + } else { + text = ""; + } + + // Do the actual text manipulation (including scrolling) on the event thread + if (!text.isEmpty() || addNewLine) { + ApplicationContext.queueCallback(() -> { + int length = textArea.getCharacterCount(); + int newLength = length; + + if (!text.isEmpty()) { + textArea.insertText(text, length); + newLength += text.length(); + } + + if (addNewLine) { + textArea.insertText("\n", newLength++); + } + + final int lastCharPos = newLength; + + // In order to allow time for the skin to render the latest additions, + // queue the actual scrolling until that is done + ApplicationContext.queueCallback(() -> { + Bounds lastCharBounds = textArea.getCharacterBounds(lastCharPos); + textArea.scrollAreaToVisible(lastCharBounds); + }); + }); + } + } + + @Override + public void close() throws IOException { + flush(); + textArea = null; + incomingCharset = null; + lineBuffer = null; + } + + @Override + public void flush() throws IOException { + checkIfOpen(); + flushLineBuffer(false); + } + + @Override + public void write(final int b) throws IOException { + if (b == '\n') { + flushLineBuffer(true); + } else if (b != '\r') { + lineBuffer.write(b); + } + } + + /** + * @return A new {@link PrintStream} using this object as the basis (and the + * same charset specified by one of the constructors). + */ + public PrintStream toPrintStream() { + try { + return new PrintStream(this, false, incomingCharset.name()); + } catch (UnsupportedEncodingException uee) { + throw new RuntimeException("Impossible unsupported encoding error!", uee); + } + } + +} Propchange: pivot/trunk/wtk/src/org/apache/pivot/wtk/util/TextAreaOutputStream.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: pivot/trunk/wtk/src/org/apache/pivot/wtk/util/package.html ------------------------------------------------------------------------------ svn:eol-style = native