001package jmri.jmrit.display.layoutEditor.configurexml; 002 003import java.awt.Color; 004import java.awt.geom.Point2D; 005import java.util.ArrayList; 006import java.util.List; 007import jmri.configurexml.AbstractXmlAdapter; 008import jmri.jmrit.display.layoutEditor.LayoutEditor; 009import jmri.jmrit.display.layoutEditor.LayoutShape; 010import jmri.util.ColorUtil; 011import org.jdom2.Attribute; 012import org.jdom2.DataConversionException; 013import org.jdom2.Element; 014 015/** 016 * This module handles configuration for LayoutShape objects for a LayoutEditor. 017 * 018 * @author George Warner Copyright (c) 2017-2018 019 */ 020public class LayoutShapeXml extends AbstractXmlAdapter { 021 022 public LayoutShapeXml() { 023 } 024 025 // default mapping fine 026 static final EnumIoNames<LayoutShape.LayoutShapeType> sTypeEnumMap 027 = new EnumIoNames<>(LayoutShape.LayoutShapeType.class); 028 static final EnumIoNames<LayoutShape.LayoutShapePointType> pTypeEnumMap 029 = new EnumIoNames<>(LayoutShape.LayoutShapePointType.class); 030 031 /** 032 * Default implementation for storing the contents of a LayoutShape 033 * 034 * @param o Object to store, of type LayoutShape 035 * @return Element containing the complete info 036 */ 037 @Override 038 public Element store(Object o) { 039 LayoutShape s = (LayoutShape) o; 040 Element element = null; 041 042 if (s.getNumberPoints() > 0) { 043 element = new Element("layoutShape"); 044 045 // include attributes 046 element.setAttribute("ident", s.getName()); 047 element.setAttribute("type", "" + sTypeEnumMap.outputFromEnum(s.getType())); 048 element.setAttribute("level", "" + s.getLevel()); 049 element.setAttribute("linewidth", "" + s.getLineWidth()); 050 element.setAttribute("lineColor", ColorUtil.colorToHexString(s.getLineColor())); 051 element.setAttribute("fillColor", ColorUtil.colorToHexString(s.getFillColor())); 052 if (s.isHidden()) { 053 element.setAttribute("hidden", "true"); 054 } 055 056 Element elementPoints = new Element("points"); 057 ArrayList<LayoutShape.LayoutShapePoint> shapePoints = s.getPoints(); 058 for (LayoutShape.LayoutShapePoint p : shapePoints) { 059 Element elementPoint = new Element("point"); 060 061 elementPoint.setAttribute("type", "" + pTypeEnumMap.outputFromEnum(p.getType())); 062 063 Point2D pt = p.getPoint(); 064 elementPoint.setAttribute("x", "" + pt.getX()); 065 elementPoint.setAttribute("y", "" + pt.getY()); 066 067 elementPoints.addContent(elementPoint); 068 } 069 element.addContent(elementPoints); 070 071 element.setAttribute("class", getClass().getName()); 072 } 073 return element; 074 } 075 076 @Override 077 public boolean load(Element shared, Element perNode) { 078 log.error("Invalid method called"); 079 return false; 080 } 081 082 /** 083 * Load, starting with the LayoutShape element, then all the other data 084 * 085 * @param element Top level Element to unpack. 086 * @param o LayoutEditor as an Object 087 */ 088 @Override 089 public void load(Element element, Object o) { 090 // create the objects 091 LayoutEditor p = (LayoutEditor) o; 092 093 String name = element.getAttribute("ident").getValue(); 094 095 LayoutShape.LayoutShapeType type = 096 sTypeEnumMap.inputFromAttribute(element.getAttribute("type")); 097 098 // create the new LayoutShape 099 LayoutShape s = new LayoutShape(name, type, p); 100 101 Attribute a = element.getAttribute("level"); 102 if (a != null) { 103 try { 104 s.setLevel(a.getIntValue()); 105 } catch (DataConversionException e) { 106 log.error("Layout Shape level attribute Conversion error."); 107 } 108 } else { 109 log.error("Layout Shape level attribute not found."); 110 } 111 112 a = element.getAttribute("linewidth"); 113 if (a != null) { 114 try { 115 s.setLineWidth(a.getIntValue()); 116 } catch (DataConversionException e) { 117 log.error("Layout Shape line width attribute Conversion error."); 118 } 119 } else { 120 log.error("Layout Shape line width attribute not found."); 121 } 122 123 a = element.getAttribute("lineColor"); 124 if (a != null) { 125 try { 126 s.setLineColor(ColorUtil.stringToColor(a.getValue())); 127 } catch (IllegalArgumentException e) { 128 s.setLineColor(Color.BLACK); 129 log.error("Invalid lineColor {}; using black", a.getValue()); 130 } 131 } 132 133 a = element.getAttribute("fillColor"); 134 if (a != null) { 135 try { 136 s.setFillColor(ColorUtil.stringToColor(a.getValue())); 137 } catch (IllegalArgumentException e) { 138 s.setFillColor(Color.BLACK); 139 log.error("Invalid fillColor {}; using black", a.getValue()); 140 } 141 } 142 143 a = element.getAttribute("hidden"); 144 if (a != null) { 145 // The attribute only exists when true 146 s.setHidden(true); 147 } 148 149 Element pointsElement = element.getChild("points"); 150 if (pointsElement != null) { 151 List<Element> elementList = pointsElement.getChildren("point"); 152 if (elementList != null) { 153 if (!elementList.isEmpty()) { 154 for (int i = 0; i < elementList.size(); i++) { 155 Element relem = elementList.get(i); 156 157 LayoutShape.LayoutShapePointType pointType = 158 pTypeEnumMap.inputFromAttribute(relem.getAttribute("type")); 159 160 double x = 0.0; 161 double y = 0.0; 162 try { 163 x = (relem.getAttribute("x")).getFloatValue(); 164 y = (relem.getAttribute("y")).getFloatValue(); 165 } catch (DataConversionException e) { 166 log.error("failed to convert Layout Shape point #{}coordinates attributes", i); 167 } 168 s.addPoint(pointType, new Point2D.Double(x, y)); 169 } 170 } else { 171 log.error("No Layout Shape point elements"); 172 } 173 } else { 174 log.error("Layout Shape point elements not found."); 175 } 176 } else { 177 log.error("Layout Shape points element not found."); 178 } 179 p.getLayoutShapes().add(s); 180 p.unionToPanelBounds(s.getBounds()); 181 } 182 183 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LayoutShapeXml.class); 184}