/** Captures this interaction in {@code ONLY} mode. This causes subsequent events in this * interaction to go only to the layer which is currently handling the interaction. Other layers * in the interaction will receive a cancellation event and nothing further. */ public void capture () { capture(CaptureMode.ONLY); }
/** Captures this interaction in the specified capture mode. Depending on the mode, subsequent * events will go only to the current layer, or that layer and its parents, or that layer and * its children. Other layers in the interaction will receive a cancellation event and nothing * further. */ public void capture (CaptureMode mode) { assert dispatchLayer != null; if (canceled) throw new IllegalStateException("Cannot capture canceled interaction."); if (capturingLayer != dispatchLayer && captured()) throw new IllegalStateException( "Interaction already captured by " + capturingLayer); capturingLayer = dispatchLayer; captureMode = mode; notifyCancel(capturingLayer, captureMode, event); }
private void notifyCancel (Layer except, CaptureMode exceptMode, E source) { E oldEvent = event; event = newCancelEvent(source); try { if (bubble) { Depth depth = Depth.BELOW; for (Layer target = hitLayer; target != null; target = target.parent()) { if (target == except) depth = Depth.AT; else if (depth == Depth.AT) depth = Depth.ABOVE; if (exceptMode != null && exceptMode.allow(depth)) continue; dispatch(target); } } else { if (hitLayer != except) dispatch(hitLayer); } } finally { this.event = oldEvent; } }
/** Cancels this interaction. All layers which normally participate in the action will be * notified of the cancellation. */ public void cancel () { if (!canceled) { notifyCancel(null, null, event); canceled = true; } }
void dispatch (E event) { // if this interaction has been manually canceled, ignore further dispatch requests if (canceled) return; assert event != null; LayerUtil.screenToLayer(hitLayer, local.set(event.x, event.y), local); this.event = event; try { if (bubble) { Depth depth = Depth.BELOW; for (Layer target = hitLayer; target != null; target = target.parent()) { if (target == capturingLayer) depth = Depth.AT; else if (depth == Depth.AT) depth = Depth.ABOVE; if (captureMode != null && !captureMode.allow(depth)) continue; dispatch(target); // the above dispatch may have caused a capture, in which case capturing layer will have // just been set and we need to update our depth accordingly if (target == capturingLayer) depth = Depth.AT; } } else { dispatch(hitLayer); } } finally { this.event = null; } local.set(0, 0); }