@Override public void updated(PropertyUpdateEvent<PPath> e) { switch (e.key) { case SNAP_X: gridVisual.setWidth((Integer) path.get(PPath.SNAP_X)); repaint(); break; case SNAP_Y: gridVisual.setHeight((Integer) path.get(PPath.SNAP_Y)); repaint(); break; case PRECISION: for (SmoothPathSegment s : spsMap.values()) s.validate(); arrow.validate(); break; case CLOSED: case SMOOTH: // TODO: Optimize updatePointList(); break; case BACKGROUND_ROOM: ResourceReference<Room> r = path.get(PPath.BACKGROUND_ROOM); setRoom(r == null ? null : r.get()); } }
@Override protected void validate() { if (segment == null) { PathPoint p = path.points.get(0); PathPoint p2 = path.points.get(1); int x = p.getX(); int y = p.getY(); calculatePoints(x, y, Math.atan2(y - p2.getY(), p2.getX() - x)); } else { segment.validate(); if (path.get(PPath.CLOSED)) { int i = segment.px.length - 1; int x = segment.px[i]; int y = segment.py[i]; int i2 = i - 1; while (i2 > 0 && sqrdist(segment.px[i2] - x, segment.py[i2] - y) < 4) i2--; calculatePoints( x + segment.bounds.x, y + segment.bounds.y, Math.atan2(segment.py[i2] - y, x - segment.px[i2])); } else { int x = segment.px[0]; int y = segment.py[0]; int i = 1; while (i < segment.px.length - 1 && sqrdist(segment.px[i] - x, segment.py[i] - y) < 4) i++; calculatePoints( x + segment.bounds.x, y + segment.bounds.y, Math.atan2(y - segment.py[i], segment.px[i] - x)); } } Rectangle bounds = new Rectangle(-1, -1); for (int i = 0; i < 4; i++) bounds.add(px[i], py[i]); for (int i = 0; i < 4; i++) { px[i] -= bounds.x; py[i] -= bounds.y; } setBounds(bounds); }
@SuppressWarnings("unchecked") private void updatePointList() { for (SmoothPathSegment sps : spsMap.values()) sps.remove(); spsMap.clear(); for (LinearPathSegment lps : lpsMap.values()) lps.remove(); lpsMap.clear(); if (arrow != null) arrow.remove(); Set<PathPoint> pps = ((HashMap<PathPoint, PointVisual>) pvMap.clone()).keySet(); int s = pvList.size(); ActiveArrayList<PathPoint> pp = path.points; int s2 = pp.size(); while (s > s2) pvList.remove(--s); pvList.ensureCapacity(s2); for (int i = 0; i < s2; i++) { PathPoint p = pp.get(i); PointVisual v = pvMap.get(p); if (v == null) { v = new PointVisual(p); pvMap.put(p, v); } else { pps.remove(p); } if (i >= s) pvList.add(v); else pvList.set(i, v); } if (pps.contains(properties.get(PPathEditor.SELECTED_POINT))) properties.put(PPathEditor.SELECTED_POINT, null); for (PathPoint pathPoint : pps) pvMap.remove(pathPoint).remove(); if (path.get(PPath.SMOOTH)) { boolean closed = path.properties.get(PPath.CLOSED); if (s2 >= 3) { PathPoint[] rpp = new PathPoint[4]; for (int i = 0; i < 4; i++) rpp[i] = pp.get(i % s2); int i2 = closed ? s2 + 1 : s2 - 2; for (int i = 1; i < i2; i++) { PathPoint p = rpp[1]; spsMap.put(p, new SmoothPathSegment(rpp)); rpp = Arrays.copyOfRange(rpp, 1, 5); rpp[3] = pp.get((i + 3) % s2); } if (!closed) { PathPoint p = pp.get(0); spsMap.put(p, new SmoothPathSegment(null, p, pp.get(1), pp.get(2))); p = pp.get(s2 - 2); spsMap.put(p, new SmoothPathSegment(pp.get(s2 - 3), p, pp.get(s2 - 1), null)); } arrow = new PathArrow(spsMap.get(pp.get(0))); } } else { if (s2 >= 2) { for (int i = 0; i < s2 - 1; i++) { PathPoint p = path.points.get(i); lpsMap.put(p, new LinearPathSegment(p, path.points.get(i + 1))); } if (path.properties.get(PPath.CLOSED)) { PathPoint p = path.points.get(s2 - 1); lpsMap.put(p, new LinearPathSegment(p, path.points.get(0))); } arrow = new PathArrow(null); } } }