@Override public void draw(Drawing context) { all = new LinkedHashSet<>(); this.breadthFirst(this.both()) .forEach( x -> { Rect r = x.properties.get(frame); { Map<String, Function<Box, FLine>> drawing = x.properties.computeIfAbsent(interactiveDrawing, k -> new LinkedHashMap<>()); if (drawing != null && drawing.size() > 0) { Iterator<Function<Box, FLine>> it = drawing.values().iterator(); while (it.hasNext()) { Function<Box, FLine> f = it.next(); FLine fl = f.apply(x); if (fl == null) it.remove(); else all.add(fl); } } } { Map<String, Supplier<FLine>> drawing = x.properties.computeIfAbsent( interactiveLines, k -> new LinkedHashMapAndArrayList<>()); if (drawing != null && drawing.size() > 0) { Iterator<Supplier<FLine>> it = drawing.values().iterator(); while (it.hasNext()) { Supplier<FLine> f = it.next(); FLine fl = f.get(); if (fl == null) it.remove(); else all.add(fl); } } } }); for (FLine f : all) f.attributes.computeIfAbsent( projectedArea, (k) -> new Cached<FLine, Object, Area>( (fline, previously) -> projectFLineToArea(fline), (fline) -> new Object[] {fline, fline.getModCount()})); }
@Override public Mouse.Dragger onMouseDown(Window.Event<Window.MouseState> e, int button) { // if we haven't been drawn, then we can't interact if (all == null) return null; Vec2 point = convertCoordinateSystem(new Vec2(e.after.x, e.after.y)); Set<FLine> hit = new LinkedHashSet<>(); Window.Event<Window.MouseState> eMarked = e /*.copy()*/; eMarked.properties.put(interaction, this); List<Mouse.Dragger> draggers = all.stream() .filter(f -> f.attributes.get(projectedArea) != null) .filter(f -> f.attributes.get(projectedArea).apply(f).contains(point.x, point.y)) .flatMap( f -> f.attributes.getOr(Mouse.onMouseDown, Collections::emptyMap).values().stream()) .map(omd -> omd.onMouseDown(eMarked, button)) .filter(x -> x != null) .collect(Collectors.toList()); if (draggers.size() > 0) { return (event, termination) -> { // event = event.copy(); event.properties.put(interaction, this); Iterator<Mouse.Dragger> it = draggers.iterator(); while (it.hasNext()) { if (!it.next().update(event, termination)) it.remove(); } return draggers.size() > 0; }; } return null; }
@Override public Mouse.Dragger onMouseMove(Window.Event<Window.MouseState> e) { if (all == null) return null; Vec2 point = convertCoordinateSystem(new Vec2(e.after.x, e.after.y)); Set<FLine> hit = new LinkedHashSet<FLine>(); Window.Event<Window.MouseState> eMarked = e /*.copy()*/; eMarked.properties.put(interaction, this); Set<FLine> intersects = all.stream() .filter(f -> f.attributes.has(projectedArea)) .filter(f -> f.attributes.get(projectedArea).apply(f).contains(point.x, point.y)) .collect(Collectors.toSet()); Set<FLine> enter = new LinkedHashSet<>(intersects); enter.removeAll(previousIntersection); Set<FLine> exit = new LinkedHashSet<>(previousIntersection); exit.removeAll(intersects); previousIntersection = intersects; List<Mouse.Dragger> draggers = intersects .stream() .flatMap( f -> f.attributes.getOr(Mouse.onMouseMove, Collections::emptyMap).values().stream()) .map(omd -> omd.onMouseMove(eMarked)) .filter(x -> x != null) .collect(Collectors.toList()); draggers.addAll( enter .stream() .flatMap( f -> f.attributes.getOr(Mouse.onMouseEnter, Collections::emptyMap).values().stream()) .map(omd -> omd.onMouseEnter(eMarked)) .filter(x -> x != null) .collect(Collectors.toList())); exit.stream() .flatMap( f -> f.attributes.getOr(Mouse.onMouseExit, Collections::emptyMap).values().stream()) .forEach(omd -> omd.onMouseExit(eMarked)); if (draggers.size() > 0) { return (event, termination) -> { // event = event.copy(); event.properties.put(interaction, this); Iterator<Mouse.Dragger> it = draggers.iterator(); while (it.hasNext()) { if (!it.next().update(event, termination)) it.remove(); } return draggers.size() > 0; }; } return null; }