001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.mappaint.styleelement; 003 004import org.openstreetmap.josm.data.osm.OsmPrimitive; 005import org.openstreetmap.josm.data.osm.Way; 006import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings; 007import org.openstreetmap.josm.data.osm.visitor.paint.StyledMapRenderer; 008import org.openstreetmap.josm.gui.mappaint.Cascade; 009import org.openstreetmap.josm.gui.mappaint.Environment; 010import org.openstreetmap.josm.gui.mappaint.Keyword; 011import org.openstreetmap.josm.tools.CheckParameterUtil; 012 013public class RepeatImageElement extends StyleElement { 014 015 public enum LineImageAlignment { TOP, CENTER, BOTTOM } 016 017 public MapImage pattern; 018 public float offset; 019 public float spacing; 020 public float phase; 021 public LineImageAlignment align; 022 023 public RepeatImageElement(Cascade c, MapImage pattern, float offset, float spacing, float phase, LineImageAlignment align) { 024 super(c, 2.9f); 025 CheckParameterUtil.ensureParameterNotNull(pattern); 026 CheckParameterUtil.ensureParameterNotNull(align); 027 this.pattern = pattern; 028 this.offset = offset; 029 this.spacing = spacing; 030 this.phase = phase; 031 this.align = align; 032 } 033 034 public static RepeatImageElement create(Environment env) { 035 MapImage pattern = NodeElement.createIcon(env, REPEAT_IMAGE_KEYS); 036 if (pattern == null) 037 return null; 038 Cascade c = env.mc.getCascade(env.layer); 039 float offset = c.get(REPEAT_IMAGE_OFFSET, 0f, Float.class); 040 float spacing = c.get(REPEAT_IMAGE_SPACING, 0f, Float.class); 041 float phase = -c.get(REPEAT_IMAGE_PHASE, 0f, Float.class); 042 043 LineImageAlignment align = LineImageAlignment.CENTER; 044 Keyword alignKW = c.get(REPEAT_IMAGE_ALIGN, Keyword.CENTER, Keyword.class); 045 if ("top".equals(alignKW.val)) { 046 align = LineImageAlignment.TOP; 047 } else if ("bottom".equals(alignKW.val)) { 048 align = LineImageAlignment.BOTTOM; 049 } 050 051 return new RepeatImageElement(c, pattern, offset, spacing, phase, align); 052 } 053 054 @Override 055 public void paintPrimitive(OsmPrimitive primitive, MapPaintSettings paintSettings, StyledMapRenderer painter, 056 boolean selected, boolean outermember, boolean member) { 057 Way w = (Way) primitive; 058 painter.drawRepeatImage(w, pattern, painter.isInactiveMode() || w.isDisabled(), offset, spacing, phase, align); 059 } 060 061 @Override 062 public boolean isProperLineStyle() { 063 return true; 064 } 065 066 @Override 067 public boolean equals(Object obj) { 068 if (obj == null || getClass() != obj.getClass()) 069 return false; 070 if (!super.equals(obj)) 071 return false; 072 final RepeatImageElement other = (RepeatImageElement) obj; 073 if (!this.pattern.equals(other.pattern)) return false; 074 if (this.offset != other.offset) return false; 075 if (this.spacing != other.spacing) return false; 076 if (this.phase != other.phase) return false; 077 if (this.align != other.align) return false; 078 return true; 079 } 080 081 @Override 082 public int hashCode() { 083 int hash = 7; 084 hash = 83 * hash + this.pattern.hashCode(); 085 hash = 83 * hash + Float.floatToIntBits(this.offset); 086 hash = 83 * hash + Float.floatToIntBits(this.spacing); 087 hash = 83 * hash + Float.floatToIntBits(this.phase); 088 hash = 83 * hash + this.align.hashCode(); 089 return hash; 090 } 091 092 @Override 093 public String toString() { 094 return "RepeatImageStyle{" + super.toString() + "pattern=[" + pattern + 095 "], offset=" + offset + ", spacing=" + spacing + 096 ", phase=" + (-phase) + ", align=" + align + '}'; 097 } 098}