Update of /cvsroot/synclast/client/src/com/synclast/ui In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv31295/src/com/synclast/ui Modified Files: BoxContainer.java Button.java Checkbox.java ColoredWidget.java Container.java FlowContainer.java GridMenu.java Input.java Label.java Menu.java Popup.java RadioButton.java SynclastCanvas.java SynclastImage.java TableContainer.java TapInputAdapter.java Widget.java WordWrapLabel.java Added Files: Style.java Log Message: This is a complete revamp of the style mechanism in Synclast. The new mechanism works kind alike CSS layer 1 applied to widgets. You create a stylesheet with a string of text that looks like a css file (see examples/SynclastUIDemo/res/*.css for examples). You set the Stylesheet on a canvas. Widgets added to that canvas will automatically pick up the styling information assoiciated with that canvas. Styles cascade according to containment, ie, if a widget doe not have a background color style but its parent does, it will get the same background. Some styles cascade, and some do not. Styles only set the "default" values for a widget. Basically, calling set() to set a widget property wil ALWAYS override any value in the stylesheet. Stylesheets can be set on a canvas before or after it is constructed, and all widgets should end up properly getting styled in either case. This means you can also change the stylesheet on a canvas at any time you want. Since Stylesheets are just parsed from a string, they can come from anywhere (the jar, constructed on the fly, downloaded from the network, etc). Though Styles are designed to be efficient, treat them with care since very complicated pages might need non trivial time to derive all their values. Style documentation on each widget still needs to be added, along with default value and cascade information. Right now, the code IS the documentation in this regard. Please report bugs as you find them. Index: Widget.java =================================================================== RCS file: /cvsroot/synclast/client/src/com/synclast/ui/Widget.java,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** Widget.java 23 Oct 2004 00:22:17 -0000 1.22 --- Widget.java 18 Sep 2006 07:59:05 -0000 1.23 *************** *** 27,31 **** import com.synclast.Event; import com.synclast.Styled; - import com.synclast.StyleSheet; /** --- 27,30 ---- *************** *** 51,57 **** public abstract class Widget implements Styled { /** Constant for style sheet property. */ ! public static final int ALIGN = 0; ! protected static final int LAST_PROPERTY = ALIGN; // X,Y coordinates are in container's coordinate system --- 50,56 ---- public abstract class Widget implements Styled { /** Constant for style sheet property. */ ! public static final Style ALIGN = new Style("align", 0, Style.CASCADE, Style.ALIGNMENT_COMBO_TABLE); ! protected static final int LAST_PROPERTY = ALIGN.getId(); // X,Y coordinates are in container's coordinate system *************** *** 65,68 **** --- 64,68 ---- protected boolean invisible; boolean invalid; + protected String classStyleName; /** *************** *** 77,80 **** --- 77,84 ---- } + public Styled getCascadeContainer() { + return container; + } + protected int getPropertyCount() { return LAST_PROPERTY + 1; *************** *** 92,96 **** */ protected void init() { ! properties = new int [getPropertyCount()]; } --- 96,103 ---- */ protected void init() { ! if(properties == null) { ! properties = new int [getPropertyCount()]; ! } ! ALIGN.set(this, Graphics.LEFT | Graphics.TOP); } *************** *** 181,191 **** * via the set() method. */ ! public void applyStyleSheet(StyleSheet sheet) { ! if (sheet != null) { sheet.applyTo(this); ! } else { init(); setBits = 0L; ! } invalidate(); } --- 188,198 ---- * via the set() method. */ ! public void applyStyleSheet() {//StyleSheet sheet) { ! /* if (sheet != null) { sheet.applyTo(this); ! } else {*/ init(); setBits = 0L; ! // } invalidate(); } *************** *** 205,208 **** --- 212,227 ---- } + public final void setDefault(Style style, int value) { + if(style != null) { + setDefault(style.getId(), value); + } + } + + public int get(Style style) { + int id = style.getId(); + return properties[id]; + //let the arrayIndexOutofbounds exception happen. + //what else can we do? + } /** * Sets a specified property to the given value. Subclasses *************** *** 217,226 **** } ! /** ! * Convenience method; equivalent to calling ! * set(property, StyleSheet.getFontValue(font)). ! */ ! public Widget set(int property, Font font) { ! return set(property, StyleSheet.getFontValue(font)); } --- 236,245 ---- } ! public Widget set(Style style, int value) { ! if(style != null) { ! return set(style.getId(), value); ! } else { ! return this; ! } } *************** *** 241,247 **** * constants for positioning from the MIDP Graphics class * and specifies which position on the widget's clipping region ! * corresponds to the (x,y) point. */ public void setPosition(int x, int y, int align) { if ((align & Graphics.LEFT) != 0) { this.x = x; --- 260,269 ---- * constants for positioning from the MIDP Graphics class * and specifies which position on the widget's clipping region ! * corresponds to the (x,y) point. A call to this method will also ! * cause the ALIGN value to be set to the value specified, as a side ! * effect of this call. */ public void setPosition(int x, int y, int align) { + set(ALIGN, align); if ((align & Graphics.LEFT) != 0) { this.x = x; *************** *** 299,301 **** --- 321,355 ---- */ protected void hideNotify() { } + + /** + * Subclasses should implement this method to declare the name they use in stylesheets. + */ + public abstract String getStyleName(); + + /** + * A selector for styles that allows additional styling of a widget beyond the styling availble from getStyleName(). See <code>StyleSheet</code> for a more detailed explanation of how classStyleName effects widget styling. + * @returnt eh classStyleName set on this widget, or null, if no classStyleName has been set. + */ + public String getClassStyleName() { + return classStyleName; + } + + /** + * A selector for styles that allows additional styling of a widget beyond the styling avialable from getStyleName(). See <code>StyleSheet</code> for a more detailed explanation of how the classStyleName effects widget styling. Since settinng this value causes the classStyleName, and hence the styling for the widget to change, this operation may be expensive, as it triggers a refetching of all applicably widget styles, an invalidation of the widget, and if a container, the same set of steps for all contained widgets. + * @param aStyleName the new classStyleName to use for this widget. + */ + public void setClassStyleName(String aStyleName) { + //Go through all this effort below, to avoid calling init unless + //absolutely necessary (because it is so expensive) + if(classStyleName == null && aStyleName == null) { + //if they are both null, then nothing to do + //also avoid null case for later checks. + return; + } else if((classStyleName == null && aStyleName != null) || + (classStyleName != null && aStyleName == null) || + (!classStyleName.equals(aStyleName))) { + classStyleName = aStyleName; + init(); + } + } } Index: SynclastCanvas.java =================================================================== RCS file: /cvsroot/synclast/client/src/com/synclast/ui/SynclastCanvas.java,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** SynclastCanvas.java 23 Oct 2004 00:22:53 -0000 1.23 --- SynclastCanvas.java 18 Sep 2006 07:59:05 -0000 1.24 *************** *** 107,111 **** // Apply the old stylesheet to the new container this.container = container; ! container.applyStyleSheet(styleSheet); } --- 107,111 ---- // Apply the old stylesheet to the new container this.container = container; ! container.applyStyleSheet();//styleSheet); } *************** *** 123,127 **** public void setStyleSheet(StyleSheet styleSheet) { this.styleSheet = styleSheet; ! container.applyStyleSheet(styleSheet); } --- 123,127 ---- public void setStyleSheet(StyleSheet styleSheet) { this.styleSheet = styleSheet; ! container.applyStyleSheet();//styleSheet); } *************** *** 166,171 **** } // Translate for container if necessary ! int align = container.properties[Widget.ALIGN]; ! // Default is top left int dx = 0; --- 166,170 ---- } // Translate for container if necessary ! int align = container.properties[Widget.ALIGN.getId()]; // Default is top left int dx = 0; Index: BoxContainer.java =================================================================== RCS file: /cvsroot/synclast/client/src/com/synclast/ui/BoxContainer.java,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** BoxContainer.java 6 Mar 2006 06:43:36 -0000 1.14 --- BoxContainer.java 18 Sep 2006 07:59:05 -0000 1.15 *************** *** 193,197 **** private void layout(Widget widget) { ! int childAlign = widget.properties[Widget.ALIGN]; if(orientation == HORIZONTAL) { widget.x = nextX; --- 193,197 ---- private void layout(Widget widget) { ! int childAlign = widget.properties[Widget.ALIGN.getId()]; if(orientation == HORIZONTAL) { widget.x = nextX; *************** *** 231,233 **** --- 231,237 ---- } } + + public String getStyleName() { + return "box"; + } } Index: WordWrapLabel.java =================================================================== RCS file: /cvsroot/synclast/client/src/com/synclast/ui/WordWrapLabel.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** WordWrapLabel.java 17 Sep 2004 23:19:40 -0000 1.1 --- WordWrapLabel.java 18 Sep 2006 07:59:05 -0000 1.2 *************** *** 22,26 **** import javax.microedition.lcdui.Font; import javax.microedition.lcdui.Graphics; - import com.synclast.StyleSheet; /** --- 22,25 ---- *************** *** 114,116 **** --- 113,119 ---- super.validate(); } + + public String getStyleName() { + return "wordwraplabel"; + } } Index: Menu.java =================================================================== RCS file: /cvsroot/synclast/client/src/com/synclast/ui/Menu.java,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** Menu.java 11 Jul 2005 16:12:45 -0000 1.19 --- Menu.java 18 Sep 2006 07:59:05 -0000 1.20 *************** *** 27,31 **** import com.synclast.Event; - import com.synclast.StyleSheet; import com.synclast.SynclastTask; --- 27,30 ---- *************** *** 65,75 **** */ public class Menu extends ColoredWidget implements KeyEventListener, Runnable { ! public static final int SELECTED_COLOR = ColoredWidget.LAST_PROPERTY + 1; ! public static final int ITEM_ALIGN = ColoredWidget.LAST_PROPERTY + 2; ! public static final int SCROLL_DELAY = ColoredWidget.LAST_PROPERTY + 3; ! public static final int SCROLL_PERIOD = ColoredWidget.LAST_PROPERTY + 4; ! public static final int DEFAULT_FONT = ColoredWidget.LAST_PROPERTY + 5; ! public static final int SELECTED_FONT = ColoredWidget.LAST_PROPERTY + 6; ! protected static final int LAST_PROPERTY = SELECTED_FONT; // Workaround for MIDP 1.0 .class access --- 64,97 ---- */ public class Menu extends ColoredWidget implements KeyEventListener, Runnable { ! public static final Style SELECTED_COLOR = new Style( ! Style.STYLE_TYPE_COLOR, "selected-color", ! ColoredWidget.LAST_PROPERTY + 1, Style.NO_CASCADE); ! public static final Style ITEM_ALIGN = new Style( ! "item-align", ColoredWidget.LAST_PROPERTY + 2, Style.NO_CASCADE, ! Style.H_ALIGNMENT_TABLE); ! public static final Style SCROLL_DELAY = new Style( ! Style.STYLE_TYPE_SIZE, "scroll-delay", ! ColoredWidget.LAST_PROPERTY + 3, Style.NO_CASCADE); ! public static final Style SCROLL_PERIOD = new Style( ! Style.STYLE_TYPE_SIZE, "scroll-period", ! ColoredWidget.LAST_PROPERTY + 4, Style.NO_CASCADE); ! public static final Style DEFAULT_FONT = new Style( ! Style.STYLE_TYPE_SIZE, "", ColoredWidget.LAST_PROPERTY + 5, Style.CASCADE); ! public static final Style SELECTED_FONT = new Style( ! Style.STYLE_TYPE_SIZE, "", ColoredWidget.LAST_PROPERTY + 6, Style.CASCADE); ! protected static final Style DEFAULT_FONT_FACE = new Style( ! "font-face", -1, Style.CASCADE, Style.FONT_FACE); ! protected static final Style DEFAULT_FONT_STYLE = Style.getAggregatedEnumerationStyle( ! "font-style", -1, Style.CASCADE, Style.FONT_STYLE); ! protected static final Style DEFAULT_FONT_SIZE = new Style( ! "font-size", -1, Style.CASCADE, Style.FONT_SIZE); ! protected static final Style SELECTED_FONT_FACE = new Style( ! "selected-font-face", -1, Style.CASCADE, Style.FONT_FACE); ! protected static final Style SELECTED_FONT_STYLE = Style.getAggregatedEnumerationStyle( ! "selected-font-style", -1, Style.CASCADE, Style.FONT_STYLE); ! protected static final Style SELECTED_FONT_SIZE = new Style( ! "selected-font-size", -1, Style.CASCADE, Style.FONT_SIZE); ! ! protected static final int LAST_PROPERTY = SELECTED_FONT.getId(); // Workaround for MIDP 1.0 .class access *************** *** 81,85 **** h = defaultFont.getHeight() * (size - 1) + selectedFont.getHeight() ! + 2 * properties[INSET_WIDTH]; } --- 103,107 ---- h = defaultFont.getHeight() * (size - 1) + selectedFont.getHeight() ! + 2 * properties[INSET_WIDTH.getId()]; } *************** *** 107,123 **** protected void init() { super.init(); ! set(INSET_WIDTH, 2); ! set(ITEM_ALIGN, Graphics.HCENTER); ! set(SCROLL_PERIOD, 50); // 50ms between scrolling each pixel ! set(SCROLL_DELAY, 2000); // 2s delay before scrolling starts ! set(SELECTED_FONT, Font.FACE_PROPORTIONAL | Font.STYLE_BOLD | Font.SIZE_MEDIUM); ! set(DEFAULT_FONT, Font.FACE_PROPORTIONAL | Font.STYLE_PLAIN | Font.SIZE_MEDIUM); } public Widget set(int property, int value) { ! if (property == DEFAULT_FONT) { ! defaultFont = StyleSheet.getFont(value); ! } else if (property == SELECTED_FONT) { ! selectedFont = StyleSheet.getFont(value); } return super.set(property,value); --- 129,152 ---- protected void init() { super.init(); ! SELECTED_COLOR.set(this, 0); ! ITEM_ALIGN.set(this, Graphics.HCENTER); ! SCROLL_DELAY.set(this, 2000); ! SCROLL_PERIOD.set(this, 50); ! int dFace = DEFAULT_FONT_FACE.get(this, Font.FACE_PROPORTIONAL); ! int dStyle = DEFAULT_FONT_STYLE.get(this, Font.STYLE_PLAIN); ! int dSize = DEFAULT_FONT_SIZE.get(this, Font.SIZE_MEDIUM); ! setDefault(DEFAULT_FONT, Style.getFontValue(Font.getFont(dFace, dStyle, dSize))); ! int sFace = DEFAULT_FONT_FACE.get(this, Font.FACE_PROPORTIONAL); ! int sStyle = DEFAULT_FONT_STYLE.get(this, Font.STYLE_BOLD); ! int sSize = DEFAULT_FONT_SIZE.get(this, Font.SIZE_MEDIUM); ! setDefault(SELECTED_FONT, Style.getFontValue(Font.getFont(sFace, sStyle, sSize))); ! INSET_WIDTH.set(this, 2); } public Widget set(int property, int value) { ! if (property == DEFAULT_FONT.getId()) { ! defaultFont = Style.getFont(value); ! } else if (property == SELECTED_FONT.getId()) { ! selectedFont = Style.getFont(value); } return super.set(property,value); *************** *** 141,152 **** int ypos = 0; for (int i = topIndex; i < topIndex + sz; i++) { ! graphics.setColor(i == selected ? properties[SELECTED_COLOR] ! : properties[FOREGROUND_COLOR]); Font toUse = (i == selected) ? selectedFont : defaultFont; graphics.setFont(toUse); int hpos = 0; ! if (properties[ITEM_ALIGN] == Graphics.HCENTER) { hpos = (w - 2 * getTotalInset()) / 2; ! } else if (properties[ITEM_ALIGN] == Graphics.RIGHT) { hpos = w - 2 * getTotalInset(); } --- 170,181 ---- int ypos = 0; for (int i = topIndex; i < topIndex + sz; i++) { ! graphics.setColor(i == selected ? properties[SELECTED_COLOR.getId()] ! : properties[FOREGROUND_COLOR.getId()]); Font toUse = (i == selected) ? selectedFont : defaultFont; graphics.setFont(toUse); int hpos = 0; ! if (properties[ITEM_ALIGN.getId()] == Graphics.HCENTER) { hpos = (w - 2 * getTotalInset()) / 2; ! } else if (properties[ITEM_ALIGN.getId()] == Graphics.RIGHT) { hpos = w - 2 * getTotalInset(); } *************** *** 154,158 **** graphics.drawString((String) items.elementAt(i % items.size()), hpos, ypos, ! properties[ITEM_ALIGN] | Graphics.TOP); ypos += toUse.getHeight(); } --- 183,187 ---- graphics.drawString((String) items.elementAt(i % items.size()), hpos, ypos, ! properties[ITEM_ALIGN.getId()] | Graphics.TOP); ypos += toUse.getHeight(); } *************** *** 229,233 **** if ((container.fixedW > 0) && (selectedFont.stringWidth(getString(selected)) > container.fixedW)) { if (scrollTask == null) { ! scrollTask = new SynclastTask(this, properties[SCROLL_DELAY], properties[SCROLL_PERIOD], true); } } --- 258,262 ---- if ((container.fixedW > 0) && (selectedFont.stringWidth(getString(selected)) > container.fixedW)) { if (scrollTask == null) { ! scrollTask = new SynclastTask(this, properties[SCROLL_DELAY.getId()], properties[SCROLL_PERIOD.getId()], true); } } *************** *** 281,283 **** --- 310,315 ---- } + public String getStyleName() { + return "menu"; + } } Index: Button.java =================================================================== RCS file: /cvsroot/synclast/client/src/com/synclast/ui/Button.java,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** Button.java 17 Sep 2004 23:12:42 -0000 1.12 --- Button.java 18 Sep 2006 07:59:05 -0000 1.13 *************** *** 20,24 **** package com.synclast.ui; - import com.synclast.StyleSheet; import com.synclast.Event; --- 20,23 ---- *************** *** 53,70 **** protected void init() { super.init(); ! set(BORDER_COLOR, Color.BLACK); ! set(BORDER_WIDTH, 1); ! set(INSET_WIDTH, 2); } public void focus() { ! properties[BORDER_WIDTH]++; ! properties[INSET_WIDTH]--; repaint(); } public void blur() { ! properties[BORDER_WIDTH]--; ! properties[INSET_WIDTH]++; repaint(); } --- 52,69 ---- protected void init() { super.init(); ! BORDER_COLOR.set(this, Color.BLACK); ! BORDER_WIDTH.set(this, 1); ! INSET_WIDTH.set(this, 2); } public void focus() { ! properties[BORDER_WIDTH.getId()]++; ! properties[INSET_WIDTH.getId()]--; repaint(); } public void blur() { ! properties[BORDER_WIDTH.getId()]--; ! properties[INSET_WIDTH.getId()]++; repaint(); } *************** *** 94,96 **** --- 93,99 ---- public boolean pointerDragged(int x, int y) { return false; } public boolean pointerReleased(int x, int y) { return false; } + + public String getStyleName() { + return "button"; + } } Index: SynclastImage.java =================================================================== RCS file: /cvsroot/synclast/client/src/com/synclast/ui/SynclastImage.java,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** SynclastImage.java 28 Jan 2004 02:33:01 -0000 1.8 --- SynclastImage.java 18 Sep 2006 07:59:05 -0000 1.9 *************** *** 35,37 **** --- 35,41 ---- h = image.getHeight(); } + + public String getStyleName() { + return "image"; + } } Index: ColoredWidget.java =================================================================== RCS file: /cvsroot/synclast/client/src/com/synclast/ui/ColoredWidget.java,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** ColoredWidget.java 17 Sep 2004 23:13:34 -0000 1.20 --- ColoredWidget.java 18 Sep 2006 07:59:05 -0000 1.21 *************** *** 20,28 **** package com.synclast.ui; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Image; - import com.synclast.StyleSheet; - /** * Base class for widgets that are rectangular or rounded and have --- 20,27 ---- package com.synclast.ui; + import java.util.Hashtable; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Image; /** * Base class for widgets that are rectangular or rounded and have *************** *** 38,65 **** */ public class ColoredWidget extends Widget { ! /** Constant for style sheet property. */ ! public static final int FOREGROUND_COLOR = Widget.LAST_PROPERTY + 1; ! /** Constant for style sheet property. */ ! public static final int BACKGROUND_COLOR = Widget.LAST_PROPERTY + 2; ! /** Constant for style sheet property. */ ! public static final int BORDER_COLOR = Widget.LAST_PROPERTY + 3; ! /** Constant for style sheet property. */ ! public static final int BORDER_ARC = Widget.LAST_PROPERTY + 4; ! /** Constant for style sheet property. */ ! public static final int BORDER_WIDTH = Widget.LAST_PROPERTY + 5; ! /** Constant for style sheet property. */ ! public static final int IMAGE_MODE = Widget.LAST_PROPERTY + 6; ! /** Constant for style sheet property. */ ! public static final int INSET_WIDTH = Widget.LAST_PROPERTY + 7; ! protected static final int LAST_PROPERTY = INSET_WIDTH; // Workaround for MIDP 1.0 .class access public static Class _class = new ColoredWidget().getClass(); - /** Constant for IMAGE_MODE property. */ - public static final int TILED = 0; - /** Constant for IMAGE_MODE property. */ - public static final int CENTERED = 1; protected Image backgroundImage; --- 37,63 ---- */ public class ColoredWidget extends Widget { ! /** Constant for IMAGE_MODE property. */ ! public static final int TILED = 0; ! /** Constant for IMAGE_MODE property. */ ! public static final int CENTERED = 1; ! public static final Style FOREGROUND_COLOR = new Style(Style.STYLE_TYPE_COLOR, "color", Widget.LAST_PROPERTY + 1, Style.CASCADE); ! public static final Style BACKGROUND_COLOR = new Style(Style.STYLE_TYPE_COLOR, "background-color", Widget.LAST_PROPERTY + 2, Style.CASCADE); ! public static final Style BORDER_COLOR = new Style(Style.STYLE_TYPE_COLOR, "border-color", Widget.LAST_PROPERTY + 3, Style.NO_CASCADE); ! public static final Style BORDER_ARC = new Style(Style.STYLE_TYPE_SIZE, "border-arc", Widget.LAST_PROPERTY + 4, Style.NO_CASCADE); ! public static final Style BORDER_WIDTH = new Style(Style.STYLE_TYPE_SIZE, "border-width", Widget.LAST_PROPERTY + 5, Style.NO_CASCADE); ! protected static final Style IMAGE_MODE; ! static { ! Hashtable imageModeMap = new Hashtable(); ! imageModeMap.put("tiled", new Integer(TILED)); ! imageModeMap.put("centered", new Integer(CENTERED)); ! IMAGE_MODE = new Style("image-mode", Widget.LAST_PROPERTY + 6, Style.NO_CASCADE, imageModeMap); ! } ! public static final Style INSET_WIDTH = new Style(Style.STYLE_TYPE_SIZE, "inset-width", Widget.LAST_PROPERTY + 7, Style.NO_CASCADE); ! protected static final int LAST_PROPERTY = INSET_WIDTH.getId(); // Workaround for MIDP 1.0 .class access public static Class _class = new ColoredWidget().getClass(); protected Image backgroundImage; *************** *** 78,83 **** protected void init() { super.init(); ! set(BACKGROUND_COLOR, Color.TRANSPARENT); ! set(BORDER_COLOR, Color.TRANSPARENT); } --- 76,86 ---- protected void init() { super.init(); ! FOREGROUND_COLOR.set(this, 0x000000); ! BACKGROUND_COLOR.set(this, Color.TRANSPARENT); ! BORDER_COLOR.set(this, Color.TRANSPARENT); ! BORDER_ARC.set(this, 0); ! BORDER_WIDTH.set(this, 0); ! IMAGE_MODE.set(this, TILED); ! INSET_WIDTH.set(this, 0); } *************** *** 91,107 **** */ public void paint(Graphics graphics) { ! int borderWidth = properties[BORDER_WIDTH]; ! if (backgroundImage == null || properties[IMAGE_MODE] == CENTERED) { ! if (properties[BACKGROUND_COLOR] != Color.TRANSPARENT) { ! graphics.setColor(properties[BACKGROUND_COLOR]); graphics.fillRoundRect(borderWidth, borderWidth, w - borderWidth * 2, h - borderWidth * 2, ! properties[BORDER_ARC], ! properties[BORDER_ARC]); } } if (backgroundImage != null) { ! switch (properties[IMAGE_MODE]) { case CENTERED: graphics.drawImage(backgroundImage, w/2, h/2, --- 94,110 ---- */ public void paint(Graphics graphics) { ! int borderWidth = properties[BORDER_WIDTH.getId()]; ! if (backgroundImage == null || properties[IMAGE_MODE.getId()] == CENTERED) { ! if (properties[BACKGROUND_COLOR.getId()] != Color.TRANSPARENT) { ! graphics.setColor(properties[BACKGROUND_COLOR.getId()]); graphics.fillRoundRect(borderWidth, borderWidth, w - borderWidth * 2, h - borderWidth * 2, ! properties[BORDER_ARC.getId()], ! properties[BORDER_ARC.getId()]); } } if (backgroundImage != null) { ! switch (properties[IMAGE_MODE.getId()]) { case CENTERED: graphics.drawImage(backgroundImage, w/2, h/2, *************** *** 128,137 **** } if (borderWidth > 0) { ! if (properties[BORDER_COLOR] != Color.TRANSPARENT) { ! graphics.setColor(properties[BORDER_COLOR]); for (int i = 0; i < borderWidth; i++) { graphics.drawRoundRect(i,i,w-1-i*2,h-1-i*2, ! properties[BORDER_ARC] - i * 2, ! properties[BORDER_ARC] - i * 2); } } --- 131,140 ---- } if (borderWidth > 0) { ! if (properties[BORDER_COLOR.getId()] != Color.TRANSPARENT) { ! graphics.setColor(properties[BORDER_COLOR.getId()]); for (int i = 0; i < borderWidth; i++) { graphics.drawRoundRect(i,i,w-1-i*2,h-1-i*2, ! properties[BORDER_ARC.getId()] - i * 2, ! properties[BORDER_ARC.getId()] - i * 2); } } *************** *** 144,148 **** graphics.translate(totalInset, totalInset); } ! graphics.setColor(properties[FOREGROUND_COLOR]); } --- 147,151 ---- graphics.translate(totalInset, totalInset); } ! graphics.setColor(properties[FOREGROUND_COLOR.getId()]); } *************** *** 157,165 **** protected int getTotalInset() { ! return properties[BORDER_WIDTH] + properties[INSET_WIDTH]; } public Widget set(int property, int value) { ! if ((property == BORDER_WIDTH) || (property == INSET_WIDTH)) { int delta = 2 * (value - properties[property]); w += delta; --- 160,169 ---- protected int getTotalInset() { ! return properties[BORDER_WIDTH.getId()] + ! properties[INSET_WIDTH.getId()]; } public Widget set(int property, int value) { ! if ((property == BORDER_WIDTH.getId()) || (property == INSET_WIDTH.getId())) { int delta = 2 * (value - properties[property]); w += delta; *************** *** 168,170 **** --- 172,179 ---- return super.set(property, value); } + + public String getStyleName() { + //in general you shouldn't be using a ColoredWidget for styling. But it is possible, so... + return "coloredwidget"; + } } Index: Container.java =================================================================== RCS file: /cvsroot/synclast/client/src/com/synclast/ui/Container.java,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** Container.java 12 Feb 2006 03:39:21 -0000 1.36 --- Container.java 18 Sep 2006 07:59:05 -0000 1.37 *************** *** 25,29 **** import com.synclast.Event; - import com.synclast.StyleSheet; /** --- 25,28 ---- *************** *** 181,186 **** * components may have been resized. */ ! public void applyStyleSheet(StyleSheet sheet) { ! super.applyStyleSheet(sheet); // Apply just the new styleSheet to contained widgets --- 180,185 ---- * components may have been resized. */ ! public void applyStyleSheet() {//StyleSheet sheet) { ! super.applyStyleSheet();//sheet); // Apply just the new styleSheet to contained widgets *************** *** 188,192 **** for (int i = widgets.size() - 1; i >= 0; --i) { widget = (Widget) widgets.elementAt(i); ! widget.applyStyleSheet(sheet); } } --- 187,191 ---- for (int i = widgets.size() - 1; i >= 0; --i) { widget = (Widget) widgets.elementAt(i); ! widget.applyStyleSheet();//sheet); } } *************** *** 197,201 **** */ protected void borderLayout(Widget widget, int width, int height) { ! int align = widget.properties[Widget.ALIGN]; if ((align & VERTICAL) != 0) { --- 196,200 ---- */ protected void borderLayout(Widget widget, int width, int height) { ! int align = widget.properties[Widget.ALIGN.getId()]; if ((align & VERTICAL) != 0) { *************** *** 253,263 **** // Apply style sheet, if available UIContext context = getContext(); ! if (context != null) { ! widget.applyStyleSheet(context.getStyleSheet()); ! } widget.setContainer(this); if(!widgets.contains(widget)) { widgets.addElement(widget); } if (context != null && context.isShown()) { widget.showNotify(); --- 252,263 ---- // Apply style sheet, if available UIContext context = getContext(); ! //add to containment, then style, so cascade works properly. widget.setContainer(this); if(!widgets.contains(widget)) { widgets.addElement(widget); } + if (context != null) { + widget.applyStyleSheet();//context.getStyleSheet()); + } if (context != null && context.isShown()) { widget.showNotify(); *************** *** 566,568 **** --- 566,572 ---- ((context != null) && context.fireEvent(event)); } + + public String getStyleName() { + return "container"; + } } Index: TapInputAdapter.java =================================================================== RCS file: /cvsroot/synclast/client/src/com/synclast/ui/TapInputAdapter.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** TapInputAdapter.java 5 Feb 2004 01:35:33 -0000 1.6 --- TapInputAdapter.java 18 Sep 2006 07:59:05 -0000 1.7 *************** *** 23,28 **** import javax.microedition.lcdui.Graphics; - import com.synclast.StyleSheet; - /** * Implements the "multitap" method of text entry. Each digit key is mapped --- 23,26 ---- Index: Checkbox.java =================================================================== RCS file: /cvsroot/synclast/client/src/com/synclast/ui/Checkbox.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** Checkbox.java 17 Sep 2004 23:12:42 -0000 1.10 --- Checkbox.java 18 Sep 2006 07:59:05 -0000 1.11 *************** *** 25,29 **** import com.synclast.Event; - import com.synclast.StyleSheet; /** --- 25,28 ---- *************** *** 43,49 **** protected void init() { super.init(); ! set(BORDER_WIDTH, 1); ! set(BORDER_COLOR, Color.BLACK); ! set(BACKGROUND_COLOR, Color.LIGHT_GRAY); } --- 42,48 ---- protected void init() { super.init(); ! BORDER_WIDTH.set(this, 1); ! BORDER_COLOR.set(this, Color.BLACK); ! BACKGROUND_COLOR.set(this, Color.LIGHT_GRAY); } *************** *** 53,62 **** public void focus() { ! properties[BORDER_WIDTH]++; repaint(); } public void blur() { ! properties[BORDER_WIDTH]--; repaint(); } --- 52,61 ---- public void focus() { ! properties[BORDER_WIDTH.getId()]++; repaint(); } public void blur() { ! properties[BORDER_WIDTH.getId()]--; repaint(); } *************** *** 105,107 **** --- 104,110 ---- public boolean pointerDragged(int x, int y) { return false; } public boolean pointerReleased(int x, int y) { return false; } + + public String getStyleName() { + return "checkbox"; + } } Index: TableContainer.java =================================================================== RCS file: /cvsroot/synclast/client/src/com/synclast/ui/TableContainer.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** TableContainer.java 28 Jan 2004 02:33:01 -0000 1.5 --- TableContainer.java 18 Sep 2006 07:59:05 -0000 1.6 *************** *** 206,208 **** --- 206,212 ---- } } + + public String getStyleName() { + return "table"; + } } Index: Input.java =================================================================== RCS file: /cvsroot/synclast/client/src/com/synclast/ui/Input.java,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** Input.java 17 Sep 2004 23:14:26 -0000 1.20 --- Input.java 18 Sep 2006 07:59:05 -0000 1.21 *************** *** 20,23 **** --- 20,24 ---- package com.synclast.ui; + import java.util.Hashtable; import java.util.Vector; *************** *** 28,32 **** import com.synclast.Event; - import com.synclast.StyleSheet; import com.synclast.SynclastTask; import com.synclast.SynclastManager; --- 29,32 ---- *************** *** 46,51 **** public class Input extends ColoredWidget implements KeyEventListener, PointerEventListener, InputHandler, Runnable { - // Workaround for MIDP 1.0 .class access - public static Class _class = new Input().getClass(); /** --- 46,49 ---- *************** *** 54,65 **** * in the text. */ ! public static final int MASK_CHAR = ColoredWidget.LAST_PROPERTY + 1; - public static final int FONT = ColoredWidget.LAST_PROPERTY + 2; - public static final int CURSOR_BLINK_DELAY = ColoredWidget.LAST_PROPERTY + 3; - public static final int MAX_SIZE = ColoredWidget.LAST_PROPERTY + 4; - public static final int WIDTH = ColoredWidget.LAST_PROPERTY + 5; ! protected static final int LAST_PROPERTY = WIDTH; private SynclastTask cursor; --- 52,86 ---- * in the text. */ ! public static final Style MASK_CHAR = new Style( ! Style.STYLE_TYPE_CHAR, "mask-char", ! ColoredWidget.LAST_PROPERTY + 1, Style.NO_CASCADE); ! public static final Style FONT = new Style( ! Style.STYLE_TYPE_SIZE, "", ! ColoredWidget.LAST_PROPERTY + 2, Style.CASCADE); ! public static final Style CURSOR_BLINK_DELAY = new Style( ! Style.STYLE_TYPE_SIZE, "cursor-blink-delay", ! ColoredWidget.LAST_PROPERTY + 3, Style.NO_CASCADE); ! public static final Style MAX_SIZE = new Style( ! Style.STYLE_TYPE_SIZE, "max-size", ! ColoredWidget.LAST_PROPERTY + 4, Style.NO_CASCADE); ! public static final Style WIDTH = new Style( ! Style.STYLE_TYPE_SIZE, "width", ! ColoredWidget.LAST_PROPERTY + 5, Style.NO_CASCADE); ! protected static final Style FONT_STYLE = ! Style.getAggregatedEnumerationStyle("font-style", -1, Style.CASCADE, ! Style.FONT_STYLE); ! protected static final Style FONT_FACE = ! new Style("font-size", -1, Style.CASCADE, ! Style.FONT_FACE); ! protected static final Style FONT_SIZE = ! new Style("font-face", -1, Style.CASCADE, ! Style.FONT_SIZE); ! ! protected static final int LAST_PROPERTY = WIDTH.getId(); ! ! // Workaround for MIDP 1.0 .class access ! public static Class _class = new Input().getClass(); private SynclastTask cursor; *************** *** 96,105 **** protected void init() { super.init(); ! set(BORDER_WIDTH, 1) ! .set(BORDER_COLOR, Color.BLACK) ! .set(INSET_WIDTH, 2) ! .set(CURSOR_BLINK_DELAY, 500) ! .set(MAX_SIZE, 10) ! .set(FONT, StyleSheet.getFontValue(Font.getDefaultFont())); } --- 117,135 ---- protected void init() { super.init(); ! MASK_CHAR.set(this, 0); ! CURSOR_BLINK_DELAY.set(this, 500); ! MAX_SIZE.set(this, 10); ! //WIDTH.set(this, 10); ! ! ! Font defaultFont = Font.getDefaultFont(); ! int fFace = FONT_FACE.get(this, defaultFont.getFace()); ! int fStyle = FONT_STYLE.get(this, defaultFont.getStyle()); ! int fSize = FONT_SIZE.get(this, defaultFont.getSize()); ! setDefault(FONT, Style.getFontValue(Font.getFont(fFace, fStyle, fSize))); ! ! BORDER_WIDTH.set(this, 1); ! BORDER_COLOR.set(this, Color.BLACK); ! INSET_WIDTH.set(this, 2); } *************** *** 135,139 **** public int getMaxSize() { ! return properties[MAX_SIZE]; } --- 165,169 ---- public int getMaxSize() { ! return properties[MAX_SIZE.getId()]; } *************** *** 148,154 **** if (text.length() > 0) { char[] temp = text.toString().toCharArray(); ! if (properties[MASK_CHAR] != 0) { for (int i = 0; i < temp.length; i++) { ! temp[i] = (char) properties[MASK_CHAR]; } } --- 178,184 ---- if (text.length() > 0) { char[] temp = text.toString().toCharArray(); ! if (properties[MASK_CHAR.getId()] != 0) { for (int i = 0; i < temp.length; i++) { ! temp[i] = (char) properties[MASK_CHAR.getId()]; } } *************** *** 168,173 **** public void backspace() { if (pos != 0) { ! pixelOffset -= font.charWidth(properties[MASK_CHAR] != 0 ? ! (char) properties[MASK_CHAR] : text.charAt(pos - 1)); text.deleteCharAt(--pos); --- 198,203 ---- public void backspace() { if (pos != 0) { ! pixelOffset -= font.charWidth(properties[MASK_CHAR.getId()] != 0 ? ! (char) properties[MASK_CHAR.getId()] : text.charAt(pos - 1)); text.deleteCharAt(--pos); *************** *** 177,184 **** public void addCharacter(char ch) { ! if (pos < properties[MAX_SIZE]) { text.insert(pos++, ch); ! if (properties[MASK_CHAR] != 0) { ! ch = (char) properties[MASK_CHAR]; } pixelOffset += font.charWidth(ch); --- 207,214 ---- public void addCharacter(char ch) { ! if (pos < properties[MAX_SIZE.getId()]) { text.insert(pos++, ch); ! if (properties[MASK_CHAR.getId()] != 0) { ! ch = (char) properties[MASK_CHAR.getId()]; } pixelOffset += font.charWidth(ch); *************** *** 227,232 **** if (pos > 0) { --pos; ! pixelOffset -= font.charWidth(properties[MASK_CHAR] != 0 ? ! (char) properties[MASK_CHAR] : text.charAt(pos)); } --- 257,262 ---- if (pos > 0) { --pos; ! pixelOffset -= font.charWidth(properties[MASK_CHAR.getId()] != 0 ? ! (char) properties[MASK_CHAR.getId()] : text.charAt(pos)); } *************** *** 235,240 **** while (direction > 0) { if (pos < text.length()) { ! pixelOffset += font.charWidth(properties[MASK_CHAR] != 0 ? ! (char) properties[MASK_CHAR] : text.charAt(pos)); pos++; --- 265,270 ---- while (direction > 0) { if (pos < text.length()) { ! pixelOffset += font.charWidth(properties[MASK_CHAR.getId()] != 0 ? ! (char) properties[MASK_CHAR.getId()] : text.charAt(pos)); pos++; *************** *** 258,265 **** public void focus() { on = true; ! properties[BORDER_WIDTH]++; ! properties[INSET_WIDTH]--; repaint(); ! int delay = properties[CURSOR_BLINK_DELAY]; if (delay > 0) { cursor = new SynclastTask(this, delay, delay, true); --- 288,295 ---- public void focus() { on = true; ! properties[BORDER_WIDTH.getId()]++; ! properties[INSET_WIDTH.getId()]--; repaint(); ! int delay = properties[CURSOR_BLINK_DELAY.getId()]; if (delay > 0) { cursor = new SynclastTask(this, delay, delay, true); *************** *** 271,276 **** public void blur() { ! properties[BORDER_WIDTH]--; ! properties[INSET_WIDTH]++; if (cursor != null) { cursor.cancel(); --- 301,306 ---- public void blur() { ! properties[BORDER_WIDTH.getId()]--; ! properties[INSET_WIDTH.getId()]++; if (cursor != null) { cursor.cancel(); *************** *** 282,312 **** public Widget set(int property, int value) { ! if (property == FONT) { if (font != null) { ! if (properties[WIDTH] == 0) { ! w -= properties[MAX_SIZE] * font.charWidth('x'); } h -= font.getHeight(); } ! font = StyleSheet.getFont(value); ! if (properties[WIDTH] == 0) { ! w += properties[MAX_SIZE] * font.charWidth('x'); } h += font.getHeight(); // Recalculate pixelOffset if (text != null) { ! if (properties[MASK_CHAR] == 0) { pixelOffset = font.substringWidth(text.toString(), 0, pos); } else { ! pixelOffset = pos * font.charWidth((char) properties[MASK_CHAR]); } } invalidate(); ! } else if (property == WIDTH) { w = value; invalidate(); ! } else if (property == MAX_SIZE) { ! if ((font != null) && (properties[WIDTH] == 0)) { ! w -= properties[MAX_SIZE] * font.charWidth('x'); w += value * font.charWidth('x'); invalidate(); --- 312,342 ---- public Widget set(int property, int value) { ! if (property == FONT.getId()) { if (font != null) { ! if (properties[WIDTH.getId()] == 0) { ! w -= properties[MAX_SIZE.getId()] * font.charWidth('x'); } h -= font.getHeight(); } ! font = Style.getFont(value); ! if (properties[WIDTH.getId()] == 0) { ! w += properties[MAX_SIZE.getId()] * font.charWidth('x'); } h += font.getHeight(); // Recalculate pixelOffset if (text != null) { ! if (properties[MASK_CHAR.getId()] == 0) { pixelOffset = font.substringWidth(text.toString(), 0, pos); } else { ! pixelOffset = pos * font.charWidth((char) properties[MASK_CHAR.getId()]); } } invalidate(); ! } else if (property == WIDTH.getId()) { w = value; invalidate(); ! } else if (property == MAX_SIZE.getId()) { ! if ((font != null) && (properties[WIDTH.getId()] == 0)) { ! w -= properties[MAX_SIZE.getId()] * font.charWidth('x'); w += value * font.charWidth('x'); invalidate(); *************** *** 326,334 **** pos = pixelOffset = 0; ! while ((pos < text.length()) && (pixelOffset < (x - properties[INSET_WIDTH] - properties[BORDER_WIDTH]))) { ! if (properties[MASK_CHAR] == 0) { pixelOffset += font.charWidth(text.charAt(pos++)); } else { ! pixelOffset += font.charWidth((char) properties[MASK_CHAR]); pos++; } --- 356,364 ---- pos = pixelOffset = 0; ! while ((pos < text.length()) && (pixelOffset < (x - properties[INSET_WIDTH.getId()] - properties[BORDER_WIDTH.getId()]))) { ! if (properties[MASK_CHAR.getId()] == 0) { pixelOffset += font.charWidth(text.charAt(pos++)); } else { ! pixelOffset += font.charWidth((char) properties[MASK_CHAR.getId()]); pos++; } *************** *** 338,340 **** --- 368,374 ---- public boolean pointerDragged(int x, int y) { return false; } public boolean pointerReleased(int x, int y) { return false; } + + public String getStyleName() { + return "input"; + } } --- NEW FILE: Style.java --- package com.synclast.ui; import com.synclast.StyleSheet; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import javax.microedition.lcdui.Font; import javax.microedition.lcdui.Graphics; /** * Style handles parsing string values from stylesheet for use by widgets. Style fulfills two prinicipal roles: * <ol> * <li>Act as a prototype for each style attribute a widget can expose, including<ol> * <li>name of style in the stylesheet</li> * <li>the type of style this instance represents, such as:<ul> * <li>a color</li> * <li>a number</li> * <li>a character</li> * <li>a set of enumerated values</li> * </ul> * <li>a numeric id for this style prototype for use by the Widget.set method</li> * <li>a default value for this style if none is found in the current stylesheet</li> * </ol> * <li>Handle the parsing of style values from the "raw" value contained by the stylesheet, into the actual value useful to the widget. Parsing is accomplished by using the type information.</li> * </ol> * This class does not define the <i>actual</i> styles the widgets have. Instead it defines the types of Styles that are possible, and each Widget declares zero or more styles that it knows how to handle. Widgets also inherit Styles from their superclasses.<br/> * Everytime a widget is added to a container, or a new stylesheet is set on the Canvas containing a widget, the style class will be used to reparse the values for that widget, based on the current stylesheet and containment hierarchy. See <code>StyleSheet</code> for a detailed explanation on how the StyleSheet mechanism cascade works. The name a widget uses for the StyleSheet, and the set of styles a widget declares, are documented on each widget. * @author Harry Evans */ public class Style { /** * The token used by aggregate styles. For example, font-style: bold,italic has a comma, that separates the aggregate values for the style "font-style". */ public static final char AGGREGATE_TOKEN = ','; /** * A simple numeric value style, used for widths and other sizes. Can be used for any simple numeric style type. */ public static final int STYLE_TYPE_SIZE = 0; /** * A style to denote colors, in hex notation. It assumes values are in AARRGGBB base 16 notation (alpha, red, grean, and blue), for example 00FF00AA, with an optional 0x prefix allows (0xFF00AA). If leading values are 0's, they can be ommitted (0x0000FF66 == 0xFF66). */ public static final int STYLE_TYPE_COLOR = 1; /** * A style to denote a single character, such as an input mask char. Will take the firct character as its returned value (so "c" == 'c' and "cat" == 'c'). */ public static final int STYLE_TYPE_CHAR = 2; /** * A style to denote a fixed set of possible values. When this style is constructed, it takes a map of possible keys, with each key mapping to a specific numeric value. This can be used, for example, as a set of "friendly" color names. k:"Red" v:"16711680", k:"Green" v:"65280", k:"Blue" v:"255" would allow friendly color names for a style. Can also map to alignment or other types. */ public static final int STYLE_TYPE_ENUMERATION = 3; /** * A style to denote a fixed set of possible values, but where there can be more than one value per key. For example, "font-style: bold,italic,underline" can be defined as an aggegated enumeration, with k:"bold" v:"Font.STYLE_BOLD" k:"italic" v:"Font.STYLE_ITALIC", k:"underline" v:"Font.STYLE_UNDERLINE". The returned value will be Font.STYLE_BOLD | Font.STYLE_ITALIC | Font.STYLE_UNDERLINE. */ public static final int STYLE_TYPE_AGGREGATED_ENUMERATION = 4; private static final String[] NAMES = { "STYLE_TYPE_SIZE", "STYLE_TYPE_COLOR", "STYLE_TYPE_CHAR", "STYLE_TYPE_ENUMERATION", "STYLE_TYPE_AGGREGATED_ENUMERATION" }; /** * Convenience table for enumerated style types, to prevent the multiple definitions of horizontal alignment types. Uses the values defined in javax.microedition.lcdui.Graphics for horizintal alignment values (LEFT, RIGHT, and CENTER). */ public static final Hashtable H_ALIGNMENT_TABLE; /** * Convenience table for enumerated style types, to prevent the multiple definitions of vertical alignment types. Uses the values defined in javax.microedition.lcdui.Graphics for vertical alignment values (TOP, VCENTER, and BOTTOM). */ public static final Hashtable V_ALIGNMENT_TABLE; /** * Convenience table for enumerated style types, to prevent the multiple definitions of horizontal and vertical alignment types. Uses the values defined in javax.microedition.lcdui.Graphics for horizontal and vertical alignment values (LEFT, CENTER, RIGHT, TOP, VCENTER, and BOTTOM). */ public static final Hashtable ALIGNMENT_COMBO_TABLE; //set of tables for font styles public static final Hashtable FONT_FACE; public static final Hashtable FONT_STYLE; public static final Hashtable FONT_SIZE; static { H_ALIGNMENT_TABLE = new Hashtable(); H_ALIGNMENT_TABLE.put("left", new Integer(Graphics.LEFT)); H_ALIGNMENT_TABLE.put("right", new Integer(Graphics.RIGHT)); H_ALIGNMENT_TABLE.put("hcenter", new Integer(Graphics.HCENTER)); V_ALIGNMENT_TABLE = new Hashtable(); V_ALIGNMENT_TABLE.put("top", new Integer(Graphics.TOP)); V_ALIGNMENT_TABLE.put("bottom", new Integer(Graphics.BOTTOM)); V_ALIGNMENT_TABLE.put("vcenter", new Integer(Graphics.VCENTER)); //there is probably a better way to do this, but for now, //just do all 24 combinations of alignments Hashtable act = new Hashtable(24); act.put("top", new Integer(Graphics.TOP)); act.put("top,left", new Integer(Graphics.TOP|Graphics.LEFT)); act.put("top,center", new Integer(Graphics.TOP|Graphics.HCENTER)); act.put("top,right", new Integer(Graphics.TOP|Graphics.RIGHT)); act.put("vcenter", new Integer(Graphics.VCENTER)); act.put("vcenter,left", new Integer(Graphics.VCENTER|Graphics.LEFT)); act.put("vcenter,center", new Integer(Graphics.VCENTER|Graphics.HCENTER)); act.put("vcenter,right", new Integer(Graphics.VCENTER|Graphics.RIGHT)); act.put("bottom", new Integer(Graphics.BOTTOM)); act.put("bottom,left", new Integer(Graphics.BOTTOM|Graphics.LEFT)); act.put("bottom,center", new Integer(Graphics.BOTTOM|Graphics.HCENTER)); act.put("bottom,right", new Integer(Graphics.BOTTOM|Graphics.RIGHT)); act.put("left", new Integer(Graphics.LEFT)); act.put("left,top", new Integer(Graphics.LEFT|Graphics.TOP)); act.put("left,vcenter", new Integer(Graphics.LEFT|Graphics.VCENTER)); act.put("left,bottom", new Integer(Graphics.LEFT|Graphics.BOTTOM)); act.put("center", new Integer(Graphics.HCENTER)); act.put("center,top", new Integer(Graphics.HCENTER|Graphics.TOP)); act.put("center,vcenter", new Integer(Graphics.HCENTER|Graphics.VCENTER)); act.put("center,bottom", new Integer(Graphics.HCENTER|Graphics.BOTTOM)); act.put("right", new Integer(Graphics.RIGHT)); act.put("right,top", new Integer(Graphics.RIGHT|Graphics.TOP)); act.put("right,vcenter", new Integer(Graphics.RIGHT|Graphics.VCENTER)); act.put("right,bottom", new Integer(Graphics.RIGHT|Graphics.BOTTOM)); ALIGNMENT_COMBO_TABLE = act; FONT_STYLE = new Hashtable(); FONT_STYLE.put("bold", new Integer(Font.STYLE_BOLD)); FONT_STYLE.put("italic", new Integer(Font.STYLE_ITALIC)); FONT_STYLE.put("plain", new Integer(Font.STYLE_PLAIN)); FONT_STYLE.put("underlined", new Integer(Font.STYLE_UNDERLINED)); FONT_SIZE = new Hashtable(); FONT_SIZE.put("large", new Integer(Font.SIZE_LARGE)); FONT_SIZE.put("medium", new Integer(Font.SIZE_MEDIUM)); FONT_SIZE.put("smalle", new Integer(Font.SIZE_SMALL)); FONT_FACE = new Hashtable(); FONT_FACE.put("monospace", new Integer(Font.FACE_MONOSPACE)); FONT_FACE.put("proportional", new Integer(Font.FACE_PROPORTIONAL)); FONT_FACE.put("system", new Integer(Font.FACE_SYSTEM)); } public static final boolean CASCADE = true; public static final boolean NO_CASCADE = false; private int type; private int id; private String name; private Hashtable enumMap; private boolean cascade; /** * Make a new Style object. In general, this is only done by widgets, not application code, and the Styles created are static final on the widget they are declared on, since style does not store instance information, and it is therefore pointless to declare it for each widget instance. * @param aType the type of this Style. One of the STYLE_XXX constants declared on this class. * @param aName the name this style will have in a StyleSheet when it is parsed. * @param anId the id used by the widget that is declaring this style. */ public Style(int aType, String aName, int anId, boolean aCascade) { type = aType; id = anId; name = aName; cascade = aCascade; } /** * Construct a Style for enumerated values. This will make a style with type= STYLE_TYPE_ENUMERATION. The hashtable passed in needs to be specially constructed. It must have keys of type String, and values of type int. When the StyleSheet value is parsed, if the resulting value is a key in this hashtable, the Integer value in this hashtable will be used. If it is not a key, the default value will be used. All keys in the <code>someValues</code> hashtable will be trimmed and changed to lowercase to make key lookup predicatable from values in the parsed stylesheet. */ public Style(String aName, int anId, boolean aCascade, Hashtable someValues) { this(STYLE_TYPE_ENUMERATION, aName, anId, aCascade); enumMap = new Hashtable(); for(Enumeration e = someValues.keys(); e.hasMoreElements();) { String key = (String)e.nextElement(); String newKey = (key == null) ? null : key.trim().toLowerCase(); enumMap.put(newKey, someValues.get(key)); } } public static Style getAggregatedEnumerationStyle(String aName, int anId, boolean aCascade, Hashtable someValues) { Style aStyle = new Style(aName, anId, aCascade, someValues); aStyle.type = STYLE_TYPE_AGGREGATED_ENUMERATION; return aStyle; } public int getType() { return type; } public int getId() { return id; } public String getName() { return name; } public boolean getCascade() { return cascade; } public String toString() { StringBuffer buf = new StringBuffer("Style["); buf.append("Type=\"").append(NAMES[type]).append("\","); buf.append("Name=\"").append(name).append("\","); buf.append("Id=\"").append(id).append("\","); buf.append("Cascade=\"").append(cascade).append("\"]"); return buf.toString(); } /** * Given a "raw" StyleSheet value, use the type for this Style to parse a useful value from it. For example, colors may be specified as "AARRGGBB" or 0xAARRGGBB", but if type is STYLE_TYPE_COLOR, will be returned as their integer value. If you are implementing a widget, and you know Style cannot parse your value, call Style.getString(Widget) to get the "raw" StyleSheet value directly. */ public int parseValue(String value, int defaultValue) { if(value == null) { return... [truncated message content] |