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

org.fxmisc.wellbehaved.event.template.InputHandlerTemplateMap Maven / Gradle / Ivy

There is a newer version: 1.11
Show newest version
package org.fxmisc.wellbehaved.event.template;

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

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

import org.fxmisc.wellbehaved.event.InputHandler.Result;
import org.fxmisc.wellbehaved.event.internal.PrefixTree;
import org.fxmisc.wellbehaved.event.internal.PrefixTree.Ops;
import org.fxmisc.wellbehaved.event.template.InputMapTemplate.HandlerTemplateConsumer;

class InputHandlerTemplateMap {

    private static  InputHandlerTemplate sequence(
            InputHandlerTemplate h1,
            InputHandlerTemplate h2) {
        return (s, evt) -> {
            switch(h1.process(s, evt)) {
                case PROCEED: return h2.process(s, evt);
                case CONSUME: return Result.CONSUME;
                case IGNORE:  return Result.IGNORE;
                default: throw new AssertionError("unreachable code");
            }
        };
    }

    private static  Ops, InputHandlerTemplate> ops() {
        return new Ops, InputHandlerTemplate>() {
            @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 InputHandlerTemplate promote(InputHandlerTemplate h,
                    EventType subTpe, EventType supTpe) {

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

            @Override
            public InputHandlerTemplate squash(InputHandlerTemplate v1, InputHandlerTemplate v2) {
                return sequence(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, InputHandlerTemplate> handlerTree;

    public InputHandlerTemplateMap() {
        this(PrefixTree.empty(ops()));
    }

    private InputHandlerTemplateMap(PrefixTree, InputHandlerTemplate> handlerTree) {
        this.handlerTree = handlerTree;
    }

    public  void insertAfter(EventType t, InputHandlerTemplate h) {
        InputHandlerTemplate handler = (InputHandlerTemplate) h;
        handlerTree = handlerTree.insert(t, handler, (h1, h2) -> sequence(h1, h2));
    }

    public  InputHandlerTemplateMap map(
            Function, ? extends InputHandlerTemplate> f) {
        return new InputHandlerTemplateMap<>(handlerTree.map(f, ops()));
    }

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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy