/* * File : BoxBase.java * Created : 12-dec-2000 11:28 * By : fbusquets * * JClic - Authoring and playing system for educational activities * * Copyright (C) 2000 - 2005 Francesc Busquets & Departament * d'Educacio de la Generalitat de Catalunya * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 (see the LICENSE file). */ package edu.xtec.jclic.boxes; import edu.xtec.jclic.Constants; import edu.xtec.jclic.misc.Gradient; import edu.xtec.util.Domable; import edu.xtec.util.FontCheck; import edu.xtec.util.JDomUtility; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Stroke; import java.awt.geom.AffineTransform; /** * This class contains all the main visual attributes needed to draw * {@link edu.xtec.jclic.boxes.AbstractBox} objects: background and foreground color * and gradient, colors for special states (inactive, alternative, disabled...), * mrgins, fonts, strokes for borders, etc. Objects derived from <CODE>AbstractBox</CODE> * can have inheritance: boxes that act as "containers" of other boxes * (like {@link edu.xtec.jclic.boxes.BoxBag}). Most of the attributes of <CODE>BoxBase</CODE> * can be <I>null</I>, meaning that the value of the ancestor, or a default value * if the box has no ancestors, must be taken. * @author Francesc Busquets (fbusquets@xtec.cat) * @version 13.08.28 */ public class BoxBase extends Object implements Cloneable, Domable{ private Font originalFont; public Color backColor; public Gradient bgGradient; public Color textColor; public Color shadowColor; public Color borderColor; public Color inactiveColor; public Color alternativeColor; public boolean shadow; public boolean transparent; public int textMargin; protected BasicStroke borderStroke, markerStroke; private Font font; private float dynFontSize; private static final float REDUCE_FONT_STEP=1; public static final float MIN_FONT_SIZE=8; private static int resetAllFontsCounter=0; public static boolean flagFontReduced=false; private int resetFontCounter; public static final Stroke DEFAULT_STROKE=new BasicStroke(1); public static final Color DEFAULT_BACK_COLOR=Color.lightGray; public static final Color DEFAULT_TEXT_COLOR=Color.black; public static final Color DEFAULT_SHADOW_COLOR=Color.gray; public static final Color DEFAULT_INACTIVE_COLOR=Color.gray; public static final Color DEFAULT_ALTERNATIVE_COLOR=Color.gray; public static final Color DEFAULT_BORDER_COLOR=Color.black; public static final float DEFAULT_BORDER_STROKE_WIDTH=0.75f; public static final BasicStroke DEFAULT_BORDER_STROKE=new BasicStroke(DEFAULT_BORDER_STROKE_WIDTH); public static final float DEFAULT_MARKER_STROKE_WIDTH=2.75f; public static final BasicStroke DEFAULT_MARKER_STROKE=new BasicStroke(DEFAULT_MARKER_STROKE_WIDTH); // default font will be build on first call to getDefaultFont(); private static Font DEFAULT_FONT=null; public static BoxBase DEFAULT_BOX_BASE=new BoxBase(); /** Creates new BoxBase */ public BoxBase() { //setFont(new Font(null)); setFont(getDefaultFont()); dynFontSize=font.getSize2D(); backColor=DEFAULT_BACK_COLOR; bgGradient=null; textColor=DEFAULT_TEXT_COLOR; shadowColor=DEFAULT_SHADOW_COLOR; inactiveColor=DEFAULT_INACTIVE_COLOR; alternativeColor=DEFAULT_ALTERNATIVE_COLOR; borderColor=DEFAULT_BORDER_COLOR; shadow=false; transparent=false; textMargin=Constants.AC_MARGIN; resetFontCounter=resetAllFontsCounter; borderStroke=DEFAULT_BORDER_STROKE; markerStroke=DEFAULT_MARKER_STROKE; } @Override public Object clone(){ BoxBase result=null; try{ result=(BoxBase)super.clone(); if(bgGradient!=null) result.bgGradient=(Gradient)bgGradient.clone(); result.setFont(originalFont); }catch(Exception ex){ System.err.println("Unexpected error cloning BoxBase!"); } return result; } @Override public boolean equals(Object o){ if(o==null) return false; boolean result=(o==this); if(!result && o instanceof BoxBase){ BoxBase bb=(BoxBase)o; result=originalFont.equals(bb.originalFont) && backColor.equals(bb.backColor) && ((bgGradient==null && bb.bgGradient==null) || (bgGradient!=null && bgGradient.equals(bb.bgGradient))) && textColor.equals(bb.textColor) && shadowColor.equals(bb.shadowColor) && borderColor.equals(bb.borderColor) && inactiveColor.equals(bb.inactiveColor) && alternativeColor.equals(bb.alternativeColor) && shadow==bb.shadow && transparent==bb.transparent && textMargin==bb.textMargin && borderStroke.equals(bb.borderStroke) && markerStroke.equals(bb.markerStroke); } return result; } public static Font getDefaultFont(){ if(DEFAULT_FONT==null) DEFAULT_FONT=FontCheck.getValidFont("Arial", Font.PLAIN, 17); return DEFAULT_FONT; } public static final String ELEMENT_NAME="style"; public static final String COLOR="color", FOREGROUND="foreground", BACKGROUND="background", SHADOW="shadow", INACTIVE="inactive", ALTERNATIVE="alternative", BORDER="border", TRANSPARENT="transparent", MARGIN="margin", BORDER_STROKE="borderStroke", MARKER_STROKE="markerStroke"; public org.jdom.Element getJDomElement(){ org.jdom.Element e=new org.jdom.Element(ELEMENT_NAME); //if(originalFont!=null) e.addContent(JDomUtility.fontToElement(originalFont)); if(!getDefaultFont().equals(originalFont)) e.addContent(JDomUtility.fontToElement(originalFont)); org.jdom.Element ce=new org.jdom.Element(COLOR); if(!textColor.equals(DEFAULT_TEXT_COLOR)) ce.setAttribute(FOREGROUND, JDomUtility.colorToString(textColor)); if(!backColor.equals(DEFAULT_BACK_COLOR)) ce.setAttribute(BACKGROUND, JDomUtility.colorToString(backColor)); if(!shadowColor.equals(DEFAULT_SHADOW_COLOR)) ce.setAttribute(SHADOW, JDomUtility.colorToString(shadowColor)); if(!inactiveColor.equals(DEFAULT_INACTIVE_COLOR)) ce.setAttribute(INACTIVE, JDomUtility.colorToString(inactiveColor)); if(!alternativeColor.equals(DEFAULT_ALTERNATIVE_COLOR)) ce.setAttribute(ALTERNATIVE, JDomUtility.colorToString(alternativeColor)); if(!borderColor.equals(DEFAULT_BORDER_COLOR)) ce.setAttribute(BORDER, JDomUtility.colorToString(borderColor)); if(!ce.getAttributes().isEmpty()) e.addContent(ce); if(bgGradient!=null) e.addContent(bgGradient.getJDomElement()); if(shadow) e.setAttribute(SHADOW, JDomUtility.boolString(shadow)); if(transparent) e.setAttribute(TRANSPARENT, JDomUtility.boolString(transparent)); if(textMargin!=Constants.AC_MARGIN) e.setAttribute(MARGIN, Integer.toString(textMargin)); if(borderStroke.getLineWidth()!=DEFAULT_BORDER_STROKE_WIDTH) e.setAttribute(BORDER_STROKE, Float.toString(borderStroke.getLineWidth())); if(markerStroke.getLineWidth()!=DEFAULT_MARKER_STROKE_WIDTH) e.setAttribute(MARKER_STROKE, Float.toString(markerStroke.getLineWidth())); return e; } public static BoxBase getBoxBase(org.jdom.Element e) throws Exception { BoxBase bb=new BoxBase(); bb.setProperties(e, null); return bb; } public void setProperties(org.jdom.Element e, Object aux) throws Exception { JDomUtility.checkName(e, ELEMENT_NAME); org.jdom.Element child; String s; if((child=e.getChild(JDomUtility.FONT))!=null){ setFont(JDomUtility.elementToFont(child)); } if((child=e.getChild(COLOR))!=null){ textColor=JDomUtility.getColorAttr(child, FOREGROUND, textColor); backColor=JDomUtility.getColorAttr(child, BACKGROUND, backColor); shadowColor=JDomUtility.getColorAttr(child, SHADOW, shadowColor); inactiveColor=JDomUtility.getColorAttr(child, INACTIVE, inactiveColor); alternativeColor=JDomUtility.getColorAttr(child, ALTERNATIVE, alternativeColor); borderColor=JDomUtility.getColorAttr(child, BORDER, borderColor); } shadow=JDomUtility.getBoolAttr(e, SHADOW, shadow); transparent=JDomUtility.getBoolAttr(e, TRANSPARENT, transparent); textMargin=JDomUtility.getIntAttr(e, MARGIN, textMargin); if((s=e.getAttributeValue(BORDER_STROKE))!=null) setBorderWidth(Float.parseFloat(s)); if((s=e.getAttributeValue(MARKER_STROKE))!=null) setMarkerWidth(Float.parseFloat(s)); if((child=e.getChild(Gradient.ELEMENT_NAME))!=null) bgGradient=Gradient.getGradient(child); } public Stroke getBorder(){ return borderStroke; } public float getBorderWidth(){ return borderStroke.getLineWidth(); } public void setBorderWidth(float w){ borderStroke=new BasicStroke(w); } public Stroke getMarker(){ return markerStroke; } public float getMarkerWidth(){ return markerStroke.getLineWidth(); } public void setMarkerWidth(float w){ markerStroke=new BasicStroke(w); } public static void resetAllFonts(){ resetAllFontsCounter++; } public void setFont(Font newFont){ if(newFont!=null){ font=newFont; dynFontSize=font.getSize(); originalFont=font.deriveFont(new AffineTransform()); } } public void resetFont(){ resetFontCounter=resetAllFontsCounter-1; } public Font getFont(){ if(resetFontCounter<resetAllFontsCounter){ resetFontCounter=resetAllFontsCounter; font=originalFont.deriveFont(new AffineTransform()); dynFontSize=font.getSize(); } return font; } public Font getOriginalFont(){ return originalFont; } public float getDynFontSize(){ return dynFontSize; } public boolean reduceFont(){ if(dynFontSize<=MIN_FONT_SIZE) return false; flagFontReduced=true; dynFontSize-=REDUCE_FONT_STEP; font=font.deriveFont(dynFontSize); return true; } }