/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.foundation; import java.awt.Color; import java.awt.geom.Dimension2D; import java.awt.geom.Point2D; import java.util.Map; import java.util.TreeMap; import java.util.logging.Logger; import org.openflexo.foundation.rm.FlexoProject; import org.openflexo.foundation.utils.FlexoColor; import org.openflexo.foundation.utils.FlexoFont; import org.openflexo.foundation.wkf.dm.LabelLocationChanged; import org.openflexo.foundation.wkf.dm.ObjectAlignementChanged; import org.openflexo.foundation.wkf.dm.ObjectLocationChanged; import org.openflexo.foundation.wkf.dm.ObjectLocationResetted; import org.openflexo.foundation.wkf.dm.ObjectSizeChanged; import org.openflexo.foundation.wkf.dm.ObjectVisibilityChanged; import org.openflexo.foundation.wkf.dm.WKFAttributeDataModification; import org.openflexo.xmlcode.PropertiesKeyValueProperty; import org.openflexo.xmlcode.StringEncoder.Converter; /** * A RepresentableFlexoModelObjectObject instance represents an object which stores data related to a potential graphical representation in * some (unknown at this level) graphical editors. Those objects are then graphically representable, and thus, have a position, a width and * a heigth <br> * This class implements the common management of basic graphical features (position, size, colors) * * @author sylvain */ public abstract class RepresentableFlexoModelObject extends FlexoModelObject { private static final Logger logger = Logger.getLogger(RepresentableFlexoModelObject.class.getPackage().getName()); public static final String DEFAULT = "default"; public static final String BG_COLOR = "bgColor"; public static final String FG_COLOR = "fgColor"; public static final String TEXT_COLOR = "textColor"; public static final String TEXT_FONT = "textFont"; public static final String POSX = "posx"; public static final String POSY = "posy"; public static final String WIDTH = "width"; public static final String HEIGHT = "height"; public static final String VISIBILITY = "visible"; public static final String LABEL_POSX = "labelx"; public static final String LABEL_POSY = "labely"; public static final String ALIGNED_ON_GRID = "alignedOnGrid"; public static final String GRID_SIZE = "gridSize"; /** * Constructor */ public RepresentableFlexoModelObject(FlexoProject project) { super(project); graphicalProperties = new TreeMap<String, Object>(); } private Map<String, Object> graphicalProperties; public Map<String, Object> _getGraphicalProperties() { if (isSerializing() && (graphicalProperties == null || graphicalProperties.size() == 0)) { return null; } return graphicalProperties; } public void _setGraphicalProperties(Map<String, Object> graphicalProperties) { this.graphicalProperties = new TreeMap<String, Object>(graphicalProperties); } public boolean hasGraphicalPropertyForKey(String key) { return graphicalProperties.get(key) != null; } public Object _graphicalPropertyForKey(String key) { Object returned = graphicalProperties.get(key); if (returned instanceof PropertiesKeyValueProperty.UndecodableProperty) { // Try to decode now Class<?> objectType; String className = ((PropertiesKeyValueProperty.UndecodableProperty) returned).className; String value = ((PropertiesKeyValueProperty.UndecodableProperty) returned).value; try { objectType = Class.forName(className); } catch (ClassNotFoundException e) { logger.warning("Class named '" + className + "' not found"); return returned; } if (objectType == FlexoColor.class) { objectType = Color.class; } Converter<?> converter = getProject().getStringEncoder()._converterForClass(objectType); if (converter == null) { // Is it an enum ??? if (objectType.isEnum()) { return Enum.valueOf((Class) objectType, value); } logger.warning("No converter for " + objectType); return returned; } returned = converter.convertFromString(value); // System.out.println("Decoding UndecodableProperty to "+objectType+" as "+returned); return returned; } return returned; } public Object _objectGraphicalPropertyForKey(String key, Object defaultValue) { Object returned = _graphicalPropertyForKey(key); if (returned == null) { // logger.warning("Cannot retrieve value for "+key+". Using default value: "+defaultValue); _setGraphicalPropertyForKey(defaultValue, key); returned = defaultValue; } return returned; } public double _doubleGraphicalPropertyForKey(String key, double defaultValue) { Object returned = _graphicalPropertyForKey(key); if (returned == null) { // logger.warning("Cannot retrieve value for "+key+". Using default value: "+defaultValue); _setGraphicalPropertyForKey(defaultValue, key); returned = defaultValue; } return (Double) returned; } public int _integerGraphicalPropertyForKey(String key, int defaultValue) { Object returned = _graphicalPropertyForKey(key); if (returned == null) { // logger.warning("Cannot retrieve value. Using default."); _setGraphicalPropertyForKey(defaultValue, key); returned = defaultValue; } return (Integer) returned; } public boolean _booleanGraphicalPropertyForKey(String key, boolean defaultValue) { Object returned = _graphicalPropertyForKey(key); if (returned == null) { // logger.warning("Cannot retrieve value. Using default."); _setGraphicalPropertyForKey(defaultValue, key); returned = defaultValue; } return (Boolean) returned; } public Color _colorGraphicalPropertyForKey(String key, Color defaultValue) { Object returned = _graphicalPropertyForKey(key); if (returned == null && defaultValue != null) { // logger.warning("Cannot retrieve value. Using default."); _setGraphicalPropertyForKey(defaultValue, key); returned = defaultValue; } return (Color) returned; } public FlexoFont _fontGraphicalPropertyForKey(String key, FlexoFont defaultValue) { Object returned = _graphicalPropertyForKey(key); if (returned == null) { // logger.warning("Cannot retrieve value. Using default."); _setGraphicalPropertyForKey(defaultValue, key); returned = defaultValue; } return (FlexoFont) returned; } // Note that following is not notified (important to avoid loops), and does NOT call setChanged() // Use high-level methods to do it (eg: setIntegerParameter()/setX()/setY()/etc....) public void _setGraphicalPropertyForKey(Object value, String key) { if (value != null) { graphicalProperties.put(key, value); } else { graphicalProperties.remove(key); } setChanged(); } public void _removeGraphicalPropertyWithKey(String key) { if (graphicalProperties.get(key) != null) { graphicalProperties.remove(key); } setChanged(); } // ================================================================ // ============ Common features graphical management ============== // ================================================================ public void setIsVisible(boolean b) { if (b != getIsVisible()) { _setGraphicalPropertyForKey(b, VISIBILITY); setChanged(); notifyObservers(new ObjectVisibilityChanged(b)); } // logger.info("setIsVisible("+b+") for "+this); // printObservers(); } public boolean getIsVisible() { return getIsVisible(false); } /** * * @param defaultVisibility * : default value when never accessed * @return */ public boolean getIsVisible(boolean defaultVisibility) { return _booleanGraphicalPropertyForKey(VISIBILITY, defaultVisibility); } public boolean getIsVisible(String context) { return getIsVisible(context, true); } public boolean getIsVisible(String context, boolean defaultValue) { return _booleanGraphicalPropertyForKey(VISIBILITY + "_" + context, defaultValue); } public void setIsVisible(boolean visible, String context) { if (visible != getIsVisible(context)) { _setGraphicalPropertyForKey(visible, VISIBILITY + "_" + context); setChanged(); notifyObservers(new ObjectVisibilityChanged(visible)); } } public boolean getIsAlignedOnGrid(String context) { return getIsAlignedOnGrid(context, false); } public boolean getIsAlignedOnGrid(String context, boolean defaultValue) { return _booleanGraphicalPropertyForKey(ALIGNED_ON_GRID + "_" + context, defaultValue); } public void setIsAlignedOnGrid(boolean isAligned, String context) { if (isAligned != getIsAlignedOnGrid(context)) { _setGraphicalPropertyForKey(isAligned, ALIGNED_ON_GRID + "_" + context); setChanged(); notifyObservers(new ObjectAlignementChanged(isAligned)); } } public int getGridSize(String context) { return getGridSize(context, 30); } public int getGridSize(String context, int defaultValue) { return _integerGraphicalPropertyForKey(GRID_SIZE + "_" + context, defaultValue); } public void setGridSize(int gridSize, String context) { if (gridSize < 1) { gridSize = 1; } if (gridSize > 200) { gridSize = 200; } if (gridSize != getGridSize(context)) { _setGraphicalPropertyForKey(gridSize, GRID_SIZE + "_" + context); setChanged(); notifyObservers(new ObjectAlignementChanged(gridSize)); } } public Point2D getLocation(String context) { return new Point2D.Double(getX(context), getY(context)); } public boolean hasLocationForContext(String context) { return hasGraphicalPropertyForKey(POSX + "_" + context) && hasGraphicalPropertyForKey(POSY + "_" + context); } public boolean hasDimensionForContext(String context) { return hasGraphicalPropertyForKey(WIDTH + "_" + context) && hasGraphicalPropertyForKey(HEIGHT + "_" + context); } public boolean hasLabelLocationForContext(String context) { return hasGraphicalPropertyForKey(getLabelXKeyForContext(context)) && hasGraphicalPropertyForKey(getLabelYKeyForContext(context)); } public void resetLocation() { setChanged(); notifyObservers(new ObjectLocationResetted()); } public void resetLocation(String context) { Point2D oldLocation = getLocation(context); _removeGraphicalPropertyWithKey(POSX + "_" + context); _removeGraphicalPropertyWithKey(POSY + "_" + context); setChanged(); notifyObservers(new ObjectLocationChanged(oldLocation, null, context)); } public void resetLabelLocation(String context) { // Point2D oldLocation = getLabelLocation(context); _removeGraphicalPropertyWithKey(getLabelXKeyForContext(context)); _removeGraphicalPropertyWithKey(getLabelYKeyForContext(context)); setChanged(); notifyObservers(new LabelLocationChanged(/*oldLocation, null, context*/)); } public double getX(String context) { return getX(context, 0); } public double getX(String context, double defaultValue) { return _doubleGraphicalPropertyForKey(POSX + "_" + context, defaultValue); } public void setX(double x, String context) { x = Math.round(x); Point2D oldLocation = getLocation(context); if (x != getX(context)) { _setGraphicalPropertyForKey(x, POSX + "_" + context); setChanged(); notifyObservers(new ObjectLocationChanged(oldLocation, getLocation(context), context)); } } public double getY(String context) { return getY(context, 0); } public double getY(String context, double defaultValue) { return _doubleGraphicalPropertyForKey(POSY + "_" + context, defaultValue); } public void setY(double y, String context) { y = Math.round(y); Point2D oldLocation = getLocation(context); if (y != getY(context)) { _setGraphicalPropertyForKey(y, POSY + "_" + context); setChanged(); notifyObservers(new ObjectLocationChanged(oldLocation, getLocation(context), context)); } } public Dimension2D getDimension(final String context) { return new Dimension2D() { @Override public double getWidth() { return RepresentableFlexoModelObject.this.getWidth(context); } @Override public double getHeight() { return RepresentableFlexoModelObject.this.getHeight(context); } @Override public void setSize(double width, double height) { } }; } public double getWidth(String context) { return getWidth(context, getDefaultWidth()); } protected int getDefaultWidth() { return 100; } public double getWidth(String context, double defaultValue) { return _doubleGraphicalPropertyForKey(WIDTH + "_" + context, defaultValue); } public void setWidth(double width, String context) { if (width != getWidth(context)) { Dimension2D oldDimension = getDimension(context); _setGraphicalPropertyForKey(width, WIDTH + "_" + context); setChanged(); notifyObservers(new ObjectSizeChanged(oldDimension, getDimension(context), context)); } } public double getHeight(String context) { return getHeight(context, getDefaultHeight()); } protected int getDefaultHeight() { return 50; } public double getHeight(String context, double defaultValue) { return _doubleGraphicalPropertyForKey(HEIGHT + "_" + context, defaultValue); } public void setHeight(double height, String context) { if (height != getHeight(context)) { Dimension2D oldDimension = getDimension(context); _setGraphicalPropertyForKey(height, HEIGHT + "_" + context); setChanged(); notifyObservers(new ObjectSizeChanged(oldDimension, getDimension(context), context)); } } public Point2D getLabelLocation(String context) { return new Point2D.Double(getLabelX(context), getLabelY(context)); } public double getLabelX(String context) { return getLabelX(context, 0); } public double getLabelX(String context, double defaultValue) { return _doubleGraphicalPropertyForKey(getLabelXKeyForContext(context), defaultValue); } public void setLabelX(double x, String context) { if (x != getLabelX(context)) { _setGraphicalPropertyForKey(x, getLabelXKeyForContext(context)); setChanged(); notifyObservers(new LabelLocationChanged()); } } public double getLabelY(String context) { return getLabelY(context, 0); } public double getLabelY(String context, double defaultValue) { return _doubleGraphicalPropertyForKey(getLabelYKeyForContext(context), defaultValue); } public void setLabelY(double y, String context) { if (y != getLabelY(context)) { _setGraphicalPropertyForKey(y, getLabelYKeyForContext(context)); setChanged(); notifyObservers(new LabelLocationChanged()); } } public static String getLabelXKeyForContext(String context) { return LABEL_POSX + "_" + context; } public static String getLabelYKeyForContext(String context) { return LABEL_POSY + "_" + context; } public Color getBgColor(String context) { return _colorGraphicalPropertyForKey(getBgColorKeyForContext(context), FlexoColor.WHITE_COLOR); } public Color getBgColor(String context, Color defaultValue) { return _colorGraphicalPropertyForKey(getBgColorKeyForContext(context), defaultValue); } public void setBgColor(Color bgColor, String context) { String key = getBgColorKeyForContext(context); _setGraphicalPropertyForKey(bgColor, key); setChanged(); notifyObservers(new DataModification(key, null, bgColor)); } public static String getBgColorKeyForContext(String context) { return BG_COLOR + "_" + context; } public Color getFgColor(String context) { return _colorGraphicalPropertyForKey(getFgColorKeyForContext(context), FlexoColor.BLACK_COLOR); } public Color getFgColor(String context, Color defaultValue) { return _colorGraphicalPropertyForKey(getFgColorKeyForContext(context), defaultValue); } public void setFgColor(Color fgColor, String context) { String key = getFgColorKeyForContext(context); _setGraphicalPropertyForKey(fgColor, key); setChanged(); notifyObservers(new DataModification(key, null, fgColor)); } public static String getFgColorKeyForContext(String context) { return FG_COLOR + "_" + context; } public Color getTextColor(String context) { return _colorGraphicalPropertyForKey(getTextColorKeyForContext(context), FlexoColor.BLACK_COLOR); } public Color getTextColor(String context, Color defaultValue) { return _colorGraphicalPropertyForKey(getTextColorKeyForContext(context), defaultValue); } public void setTextColor(Color textColor, String context) { String key = getTextColorKeyForContext(context); _setGraphicalPropertyForKey(textColor, key); setChanged(); notifyObservers(new DataModification(key, null, textColor)); } public static String getTextColorKeyForContext(String context) { return TEXT_COLOR + "_" + context; } public FlexoFont getTextFont(String context) { return _fontGraphicalPropertyForKey(getTextFontKeyForContext(context), FlexoFont.SANS_SERIF); } public FlexoFont getTextFont(String context, FlexoFont defaultValue) { return _fontGraphicalPropertyForKey(getTextFontKeyForContext(context), defaultValue); } public void setTextFont(FlexoFont textFont, String context) { String key = getTextFontKeyForContext(context); _setGraphicalPropertyForKey(textFont, key); setChanged(); notifyObservers(new DataModification(key, null, textFont)); } public static String getTextFontKeyForContext(String context) { return TEXT_FONT + "_" + context; } public int getIntegerParameter(String key) { return getIntegerParameter(key, 0); } public int getIntegerParameter(String key, int defaultValue) { return _integerGraphicalPropertyForKey(key, defaultValue); } public void setIntegerParameter(int value, String key) { int oldValue = getIntegerParameter(key); if (oldValue != value) { _setGraphicalPropertyForKey(value, key); setChanged(); notifyObservers(new WKFAttributeDataModification(key, oldValue, value)); } } public void setIntegerParameter(int value, String key, int defaultValue) { int oldValue = getIntegerParameter(key, defaultValue); if (oldValue != value) { _setGraphicalPropertyForKey(value, key); setChanged(); notifyObservers(new WKFAttributeDataModification(key, oldValue, value)); } } /*public boolean getBooleanParameter(String key) { return getBooleanParameter(key,false); } public boolean getBooleanParameter(String key, boolean defaultValue) { return _booleanGraphicalPropertyForKey(key,defaultValue); } public void setBooleanParameter(boolean value, String key) { boolean oldValue = getBooleanParameter(key); if (oldValue != value) { _setGraphicalPropertyForKey(value,key); setChanged(); notifyObservers(new WKFAttributeDataModification(key,oldValue,value)); } } public void setBooleanParameter(boolean value, String key, boolean defaultValue) { boolean oldValue = getBooleanParameter(key,defaultValue); if (oldValue != value) { _setGraphicalPropertyForKey(value,key); setChanged(); notifyObservers(new WKFAttributeDataModification(key,oldValue,value)); } }*/ }