package org.droiddraw.widget; import java.awt.Graphics; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Vector; import org.droiddraw.AndroidEditor; import org.droiddraw.property.ColorProperty; import org.droiddraw.property.Property; import org.droiddraw.property.SelectProperty; import org.droiddraw.property.StringProperty; import org.droiddraw.util.DisplayMetrics; public abstract class AbstractWidget implements Widget { int x, y; int[] padding; int baseline; int width, height; String tagName; Vector<Property> props; PropertyChangeListener listener; protected StringProperty id; protected static int widget_num = 0; Layout parent; StringProperty widthProp; StringProperty heightProp; StringProperty pad; SelectProperty visibility; StringProperty marginBottom; StringProperty marginTop; StringProperty marginLeft; StringProperty marginRight; ColorProperty background; public AbstractWidget(String tagName) { this.tagName = tagName; this.props = new Vector<Property>(); this.id = new StringProperty("Id", "android:id", ""); this.id.setStringValue("@+id/widget"+(widget_num++)); this.widthProp = new StringProperty("Width", "android:layout_width", ""); this.widthProp.setStringValue("wrap_content"); this.heightProp = new StringProperty("Height", "android:layout_height", ""); this.heightProp.setStringValue("wrap_content"); this.background = new ColorProperty("Background Color", "android:background", null); this.pad = new StringProperty("Padding", "android:padding", "0px"); this.visibility = new SelectProperty("Visible", "android:visibility", new String[] {"visible", "invisible", "gone"}, 0); this.marginTop = new StringProperty("Top Margin", "android:layout_marginTop", "0px"); this.marginBottom = new StringProperty("Bottom Margin", "android:layout_marginBottom", "0px"); this.marginLeft = new StringProperty("Left Margin", "android:layout_marginLeft", "0px"); this.marginRight = new StringProperty("Right Margin", "android:layout_marginRight", "0px"); this.padding = new int[4]; this.props.add(id); this.props.add(widthProp); this.props.add(heightProp); this.props.add(background); this.props.add(pad); this.props.add(visibility); this.props.add(marginTop); this.props.add(marginBottom); this.props.add(marginLeft); this.props.add(marginRight); this.baseline = 14; this.parent = null; } public void setPropertyChangeListener(PropertyChangeListener l) { this.listener = l; } public Layout getParent() { return parent; } public void setParent(Layout parent) { this.parent = parent; ((AbstractWidget)parent).parentTest(this); } public void parentTest(Widget w) { try { if (w == this) throw new IllegalArgumentException("BAD!"); } catch (Exception ex) { ex.printStackTrace(); System.exit(0); } if (getParent() != null) { ((AbstractWidget)getParent()).parentTest(w); } } public String getId() { return id.getStringValue(); } public void setId(String id) { this.id.setStringValue(id); } public Vector<Property> getProperties() { return props; } public void addProperty(Property p) { if (!props.contains(p)) { props.add(p); } if (listener != null) listener.propertyChange(new PropertyChangeEvent(this, "properties", null, props)); } public void removeProperty(Property p) { props.remove(p); if (listener != null) listener.propertyChange(new PropertyChangeEvent(this, "properties", null, props)); } public Property getPropertyByAttName(String attName) { for (Property prop : props) { if (prop.getAtttributeName().equals(attName)) { return prop; } } return null; } public boolean propertyHasValueByAttName(String attName, Object value) { for (Property prop : props) { if (prop.getAtttributeName().equals(attName) && prop.getValue().equals(value)) { return true; } } return false; } public void setPropertyByAttName(String attName, String value) { Property p = getPropertyByAttName(attName); if (p != null) { p.setValue(value); } else { props.add(new StringProperty(attName, attName, value)); } } public void setPosition(int x, int y) { this.x = x; this.y = y; } public void setWidth(int width) { this.widthProp.setStringValue(width+"px"); apply(); } public void setHeight(int height) { this.heightProp.setStringValue(height+"px"); apply(); } public void setSize(int width, int height) { this.widthProp.setStringValue(width+"px"); this.heightProp.setStringValue(height+"px"); apply(); } public int getX() { return x; } public int getY() { return y; } public int getWidth() { return width; } public int getHeight() { return height; } public boolean clickedOn(int x, int y) { int off_x = 0; int off_y = 0; if (parent != null) { off_x = parent.getScreenX(); off_y = parent.getScreenY(); } return (x > this.getX()+off_x && x < this.getX()+off_x+getWidth() && y > this.getY()+off_y && y < this.getY()+getHeight()+off_y); } public void move(int dx, int dy) { setPosition(this.x+dx, this.y+dy); } public String getTagName() { return tagName; } protected void readWidthHeight() { int w = DisplayMetrics.readSize(widthProp); int h = DisplayMetrics.readSize(heightProp); if (w < 0) { w = getWidth(); } if (h < 0) { h = getHeight(); } try { setPadding(DisplayMetrics.readSize(pad.getStringValue())); } catch (NumberFormatException ex) {} if (widthProp.getStringValue().equals("wrap_content")) { w = getContentWidth(); } if (heightProp.getStringValue().equals("wrap_content")) { h = getContentHeight(); } if (widthProp.getStringValue().equals("fill_parent")) { if (getParent() != null) { StringProperty prop = (StringProperty)parent.getPropertyByAttName("android:layout_width"); if (prop.getStringValue().equals("wrap_content")) w = getContentWidth(); else w = getParent().getWidth(); } else { w = AndroidEditor.instance().getScreenX()-AndroidEditor.OFFSET_X; } w = w-getX()-padding[RIGHT]; } if (heightProp.getStringValue().equals("fill_parent")) { if (getParent() != null) { StringProperty prop = (StringProperty)parent.getPropertyByAttName("android:layout_height"); if (prop.getStringValue().equals("wrap_content")) h = getContentHeight(); else h = getParent().getHeight(); } else { h = AndroidEditor.instance().getScreenY(); } h = h-getY()-padding[BOTTOM]; } width = w; height = h; } public void apply() { readWidthHeight(); if (getParent() == null) { setPosition(getPadding(LEFT)+AndroidEditor.OFFSET_X, getPadding(TOP)+AndroidEditor.OFFSET_Y); } if (widthProp.getStringValue().equals("fill_parent")) { x = padding[LEFT]; } if (heightProp.getStringValue().equals("fill_parent") && this.getParent() != null) { y = padding[TOP]; } //if (getParent() != null) { // getParent().repositionAllWidgets(); //} } public void setSizeInternal(int w, int h) { this.width = w; this.height = h; } public int getBaseline() { return baseline; } public void drawBackground(Graphics g) { if (background.getColorValue() != null) { g.setColor(background.getColorValue()); g.fillRect(getX()-getPadding(LEFT), getY()-getPadding(TOP), getWidth()+getPadding(LEFT)+getPadding(RIGHT), getHeight()+getPadding(TOP)+getPadding(BOTTOM)); } } public void setPadding(int pad) { setPadding(pad, TOP); setPadding(pad, LEFT); setPadding(pad, BOTTOM); setPadding(pad, RIGHT); } public void setPadding(int pad, int which) { padding[which] = pad; } public int getPadding(int which) { return padding[which]; } public int getMargin(int which) { switch (which) { case TOP: return DisplayMetrics.readSize(marginTop); case BOTTOM: return DisplayMetrics.readSize(marginBottom); case LEFT: return DisplayMetrics.readSize(marginLeft); case RIGHT: return DisplayMetrics.readSize(marginRight); default: return 0; } } public boolean isVisible() { return visibility.getStringValue().equals("visible"); } protected abstract int getContentWidth(); protected abstract int getContentHeight(); }