package org.bbssh.ui.components; import net.rim.device.api.ui.Color; import net.rim.device.api.ui.Field; import net.rim.device.api.ui.Font; import net.rim.device.api.ui.Graphics; import net.rim.device.api.ui.Keypad; import net.rim.device.api.ui.component.LabelField; public class SimpleButtonField extends Field { public static final int BORDER_STYLE_TOP_ONLY = 1; public static final int BORDER_STYLE_RECT = 2; public static final int BORDER_STYLE_ROUND_RECT = 3; public static final int BORDER_STYLE_NONE = 0; public static int CONTEXT_BUTTON_CLICKED = 150; private String label = ""; private int textColorUnfocused; private int textColorFocused; private int backgroundColorUnfocused; private int backgroundColorFocused; private int preferredHeight; private int preferredWidth; private int horizontalPadding = 2; private int verticalPadding = 2; private int borderColor = 0xEEEEEEEE; private int borderStyle; /** * Constructor * * @param label label to display * @param textColorUnfocused color of text when button does not have focus * @param textColorFocused color of text when button has focus * @param backgroundColorUnfocused background color when buttno does not have focus * @param backgroundColorFocused backgruond color when button has focus. * @param style style flags */ public SimpleButtonField(String label, int textColorUnfocused, int textColorFocused, int backgroundColorUnfocused, int backgroundColorFocused, long style) { super(style); if (label == null) label = ""; this.label = label; this.textColorUnfocused = textColorUnfocused; this.textColorFocused = textColorFocused; this.backgroundColorUnfocused = backgroundColorUnfocused; this.backgroundColorFocused = backgroundColorFocused; Font font = getFont(); preferredHeight = font.getHeight() + (verticalPadding * 2); preferredWidth = font.getAdvance(label) + (horizontalPadding * 2); } public SimpleButtonField(String label, long style) { this(label, Color.LIGHTGREY, Color.WHITE, Color.DARKGRAY, Color.LIGHTGREY, style); } public SimpleButtonField(long style) { this("", Color.LIGHTGREY, Color.WHITE, Color.DARKGRAY, Color.LIGHTGREY, 0); } /* * (non-Javadoc) * @see net.rim.device.api.ui.Field#onFocus(int) */ protected void onFocus(int direction) { super.onFocus(direction); invalidate(); } /* * (non-Javadoc) * @see net.rim.device.api.ui.Field#onUnfocus() */ protected void onUnfocus() { super.onUnfocus(); invalidate(); } /* * (non-Javadoc) * @see net.rim.device.api.ui.Field#isFocusable() */ public boolean isFocusable() { return true; } /** * @return the color of text to use when button does not haev focus. */ public int getTextColorUnfocused() { return this.textColorUnfocused; } /** * @param textColorUnfocused text color to use when button does not have focus */ public void setTextColorUnfocused(int textColorUnfocused) { this.textColorUnfocused = textColorUnfocused; } /** * @return the text color when control is focused. */ public int getTextColorFocused() { return this.textColorFocused; } /** * set text color to use when control has focus. * * @param textColorFocused color to use */ public void setTextColorFocused(int textColorFocused) { this.textColorFocused = textColorFocused; } /** * @return the unfocused background color */ public int getBackgroundColorUnfocused() { return this.backgroundColorUnfocused; } /** * Set the background color to use when the control has focus. * * @param backgroundColorUnfocused color to use */ public void setBackgroundColorUnfocused(int backgroundColorUnfocused) { this.backgroundColorUnfocused = backgroundColorUnfocused; } /** * @return the background color when control has focus */ public int getBackgroundColorFocused() { return this.backgroundColorFocused; } /** * Set background color to use when control has focus. * * @param backgroundColorFocused color to use */ public void setBackgroundColorFocused(int backgroundColorFocused) { this.backgroundColorFocused = backgroundColorFocused; } /** * @return the horizontal padding */ public int getHorizontalPadding() { return horizontalPadding; } /** * @return the vertical padding */ public int getVerticalPadding() { return verticalPadding; } public int getPreferredHeight() { return preferredHeight; } public int getPreferredWidth() { return preferredWidth; } protected void layout(int maxWidth, int maxHeight) { // Respect the maximum width and height available from our manager setExtent(Math.min(preferredWidth, maxWidth), Math.min(preferredHeight, maxHeight)); } protected void paint(Graphics graphics) { // Draw background boolean focus = isFocus(); int width = getWidth(); int height = getHeight(); graphics.setColor(focus ? backgroundColorFocused : backgroundColorUnfocused); graphics.fillRect(0, 0, width, height); graphics.setColor(borderColor); // Color.LIGHTGRAY is 5.0 only // @todo - BorderStyle option - rect, none, roundrect. switch (borderStyle) { case BORDER_STYLE_TOP_ONLY: graphics.drawLine(0, 0, width, 0); break; case BORDER_STYLE_RECT: graphics.drawRect(0, 0, width, height); break; case BORDER_STYLE_ROUND_RECT: case BORDER_STYLE_NONE: } graphics.setColor(focus ? getTextColorFocused(): getTextColorUnfocused()); drawText(graphics); } public void drawText(Graphics graphics) { int width = getWidth(); int fontWidth = getFont().getAdvance(label); int x; int style = getFieldStyle(); if ((style & LabelField.FIELD_HCENTER) > 0) { x = (width - (fontWidth / 2)); } else if ((style & LabelField.FIELD_RIGHT) > 0) { x = (width - fontWidth - getHorizontalPadding()); } else { x = getHorizontalPadding(); } graphics.drawText(getLabel(), x, getVerticalPadding()); } protected void drawFocus(Graphics graphics, boolean on) { // Don't draw the default focus } // @todo - touch support? Crap.. how do we make a BASE class platform-specific... ugh. /** * This override invokes fieldChangeNotify if navigation is pressed. * * @param status * @param time * @see net.rim.device.api.ui.Field#navigationClick(int, int) */ protected boolean navigationClick(int status, int time) { onClicked(); return true; } /** * This override invokes fieldChangeNotify if enter is pressed while this button has focus. * * @param keycode * @param time * @see net.rim.device.api.ui.Field#keyDown(int, int) */ protected boolean keyDown(int keycode, int time) { int key = Keypad.key(keycode); if (key == Keypad.KEY_ENTER || key == Keypad.KEY_SPACE) { onClicked(); return true; } return super.keyDown(keycode, time); } public void onClicked() { fieldChangeNotify(CONTEXT_BUTTON_CLICKED); } /** * @return this field's label */ public String getLabel() { return label; } /** * Changes the text label of this button. Note that at present, this will <b>not</b> cause the control to resize if * the text extent changes. * * @param label new text to display */ public void setLabel(String label) { this.label = label; updateSizeAndRefresh(); } public void setPadding(int vertical, int horizontal) { if (vertical > -1) this.verticalPadding = vertical; if (horizontal > -1) this.horizontalPadding = horizontal; updateSizeAndRefresh(); } private void updateSizeAndRefresh() { Font font = getFont(); preferredHeight = font.getHeight() + (verticalPadding * 2); preferredWidth = font.getAdvance(label) + (horizontalPadding * 2); updateLayout(); } public void setFont(Font font) { super.setFont(font); updateSizeAndRefresh(); } /** * @return the borderColor */ public int getBorderColor() { return this.borderColor; } /** * @param borderColor the borderColor to set */ public void setBorderColor(int borderColor) { this.borderColor = borderColor; } /** * @param verticalPadding the verticalPadding to set */ public void setVerticalPadding(int verticalPadding) { this.verticalPadding = verticalPadding; updateSizeAndRefresh(); } public void setBorderStyle(int borderStyle) { this.borderStyle = borderStyle; updateSizeAndRefresh(); } }