All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fxmisc.wellbehaved.event.InputHandlerMap Maven / Gradle / Ivy

package org.fxmisc.wellbehaved.event;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.function.BiFunction;

import javafx.event.Event;
import javafx.event.EventType;

import org.fxmisc.wellbehaved.event.InputHandler.Result;
import org.fxmisc.wellbehaved.event.InputMap.HandlerConsumer;
import org.fxmisc.wellbehaved.event.internal.PrefixTree;
import org.fxmisc.wellbehaved.event.internal.PrefixTree.Ops;

class InputHandlerMap {

    private final BiFunction, InputHandler, InputHandler> SEQ =
            (h1, h2) -> evt -> {
                switch(h1.process(evt)) {
                    case PROCEED: return h2.process(evt);
                    case CONSUME: return Result.CONSUME;
                    case IGNORE:  return Result.IGNORE;
                    default: throw new AssertionError("unreachable code");
                }
            };

    private final Ops, InputHandler> OPS = new Ops, InputHandler>() {

        @Override
        public boolean isPrefixOf(EventType t1, EventType t2) {
            EventType t = t2;
            while(t != null) {
                if(t.equals(t1)) {
                    return true;
                } else {
                    t = t.getSuperType();
                }
            }
            return false;
        }

        @Override
        public EventType commonPrefix(
                EventType t1, EventType t2) {
            Iterator> i1 = toList(t1).iterator();
            Iterator> i2 = toList(t2).iterator();
            EventType common = null;
            while(i1.hasNext() && i2.hasNext()) {
                EventType c1 = i1.next();
                EventType c2 = i2.next();
                if(Objects.equals(c1, c2)) {
                    common = c1;
                }
            }
            return (EventType) common;
        }

        @Override
        public InputHandler promote(InputHandler h,
                EventType subTpe, EventType supTpe) {

            if(Objects.equals(subTpe, supTpe)) {
                return h;
            }
            return evt -> {
                if(isPrefixOf(subTpe, (EventType) evt.getEventType())) {
                    return h.process(evt);
                } else {
                    return Result.PROCEED;
                }
            };
        }

        @Override
        public InputHandler squash(InputHandler v1, InputHandler v2) {
            return SEQ.apply(v1, v2);
        }

    };


    private static final List> toList(EventType t) {
        List> l = new ArrayList<>();
        while(t != null) {
            l.add(t);
            t = t.getSuperType();
        }
        Collections.reverse(l);
        return l;
    }

    private PrefixTree, InputHandler> handlerTree = PrefixTree.empty(OPS);

    public  void insertAfter(EventType t, InputHandler h) {
        InputHandler handler = (InputHandler) h;
        handlerTree = handlerTree.insert(t, handler, SEQ);
    }

    void forEach(HandlerConsumer f) {
        handlerTree.entries().forEach(th -> f.accept(th.getKey(), th.getValue()));
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy