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

io.github.interacto.jfx.binding.Binder Maven / Gradle / Ivy

The newest version!
/*
 * Interacto
 * Copyright (C) 2020 Arnaud Blouin
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see .
 */
package io.github.interacto.jfx.binding;

import io.github.interacto.command.Command;
import io.github.interacto.interaction.InteractionData;
import io.github.interacto.jfx.binding.api.BaseBinder;
import io.github.interacto.jfx.binding.api.CmdBinder;
import io.github.interacto.jfx.binding.api.InteractionBinder;
import io.github.interacto.jfx.binding.api.InteractionCmdBinder;
import io.github.interacto.jfx.binding.api.LogLevel;
import io.github.interacto.jfx.instrument.JfxInstrument;
import io.github.interacto.jfx.interaction.JfxInteraction;
import io.github.interacto.jfx.interaction.help.HelpAnimation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.ObservableList;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;

/**
 * The base class that defines the concept of binding builder (called binder).
 * @param  The type of the widgets.
 * @param  The type of the action to produce.
 * @param  The type of the user interaction to bind.
 * @author Arnaud Blouin
 */
abstract class Binder, D extends InteractionData>
		implements CmdBinder, InteractionBinder, InteractionCmdBinder, BaseBinder {
	protected BiConsumer initCmd;
	protected Predicate checkConditions;
	protected Function cmdProducer;
	protected List widgets;
	protected Supplier interactionSupplier;
	protected JfxInstrument instrument;
	protected boolean async;
	protected BiConsumer hadEffectsFct;
	protected BiConsumer hadNoEffectFct;
	protected BiConsumer cannotExecFct;
	protected BiConsumer onEnd;
	protected boolean consumeEvents;
	protected List> additionalWidgets;
	protected EnumSet logLevels;
	protected HelpAnimation helpAnimation;
	protected boolean withHelp;
	protected DoubleProperty progressProp;
	protected StringProperty msgProp;
	protected Button cancel;
	protected BindingsObserver observer;

	Binder(final JfxInstrument ins, final BindingsObserver observer) {
		this(null, null, null, Collections.emptyList(), null,
			ins, false, null, Collections.emptyList(), EnumSet.noneOf(LogLevel.class),
			null, false, null, null, null, null, null, null, observer, false);
	}

	Binder(final BiConsumer initCmd, final Predicate checkConditions, final Function cmdProducer, final List widgets,
			final Supplier interactionSupplier, final JfxInstrument instrument, final boolean async, final BiConsumer onEnd,
			final List> additionalWidgets, final EnumSet logLevels, final HelpAnimation helpAnimation,
			final boolean withHelp, final DoubleProperty progressProp, final StringProperty msgProp, final Button cancel,
			final BiConsumer hadNoEffectFct, final BiConsumer hadEffectsFct, final BiConsumer cannotExecFct,
			final BindingsObserver observer, final boolean consumeEvents) {
		super();
		this.initCmd = initCmd;
		this.checkConditions = checkConditions;
		this.cmdProducer = cmdProducer;
		this.widgets = widgets;
		this.interactionSupplier = interactionSupplier;
		this.instrument = instrument;
		this.async = async;
		this.onEnd = onEnd;
		this.hadEffectsFct = hadEffectsFct;
		this.hadNoEffectFct = hadNoEffectFct;
		this.cannotExecFct = cannotExecFct;
		this.additionalWidgets = additionalWidgets;
		this.logLevels = logLevels;
		this.helpAnimation = helpAnimation;
		this.withHelp = withHelp;
		this.progressProp = progressProp;
		this.msgProp = msgProp;
		this.cancel = cancel;
		this.observer = observer;
		this.consumeEvents = consumeEvents;
	}

	protected abstract Binder duplicate();

	@Override
	public Binder on(final W... widget) {
		final List w;

		if(widgets.isEmpty()) {
			w = List.of(widget);
		}else {
			w = new ArrayList<>(widgets);
			w.addAll(Arrays.asList(widget));
		}

		final Binder dup = duplicate();
		dup.widgets = w;
		return dup;
	}


	@Override
	public Binder on(final ObservableList widgets) {
		final List> adds;

		if(additionalWidgets == null) {
			adds = List.of(widgets);
		}else {
			adds = new ArrayList<>(additionalWidgets);
			adds.add(widgets);
		}

		final Binder dup = duplicate();
		dup.additionalWidgets = adds;
		return dup;
	}


	@Override
	public Binder first(final Consumer initCmdFct) {
		return first((i, c) -> initCmdFct.accept(c));
	}

	@Override
	public Binder first(final BiConsumer initCmdFct) {
		final Binder dup = duplicate();
		dup.initCmd = initCmdFct;
		return dup;
	}

	@Override
	public Binder when(final Predicate checkCmd) {
		final Binder dup = duplicate();
		dup.checkConditions = checkCmd;
		return dup;
	}

	@Override
	public Binder when(final BooleanSupplier checkCmd) {
		return when(i -> checkCmd.getAsBoolean());
	}

	@Override
	public Binder async(final Button cancel, final DoubleProperty progressProp, final StringProperty msgProp) {
		final Binder dup = duplicate();
		dup.async = true;
		dup.progressProp = progressProp;
		dup.msgProp = msgProp;
		dup.cancel = cancel;
		return dup;
	}

	@Override
	public Binder ifHadEffects(final BiConsumer hadEffectsFct) {
		final Binder dup = duplicate();
		dup.hadEffectsFct = hadEffectsFct;
		return dup;
	}

	@Override
	public Binder ifHadNoEffect(final BiConsumer noEffectFct) {
		final Binder dup = duplicate();
		dup.hadNoEffectFct = noEffectFct;
		return dup;
	}

	@Override
	public Binder end(final Consumer onEnd) {
		return end((i, c) -> onEnd.accept(c));
	}

	@Override
	public Binder end(final Runnable endFct) {
		return end((i, c) -> endFct.run());
	}

	@Override
	public Binder consume() {
		final Binder dup = duplicate();
		dup.consumeEvents = true;
		return dup;
	}

	@Override
	public Binder end(final BiConsumer onEndFct) {
		final Binder dup = duplicate();
		dup.onEnd = onEndFct;
		return dup;
	}

	@Override
	public Binder log(final LogLevel... level) {
		final Binder dup = duplicate();
		dup.logLevels = EnumSet.copyOf(Arrays.asList(level));
		return dup;
	}

	@Override
	public Binder help(final HelpAnimation animation) {
		final Binder dup = duplicate();
		dup.helpAnimation = animation;
		dup.withHelp = animation != null;
		return dup;
	}

	@Override
	public Binder help(final Pane helpPane) {
		final Binder dup = duplicate();
		dup.withHelp = true;
		return dup;
	}

	@Override
	public , D2 extends InteractionData> Binder usingInteraction(final Supplier interactionSupplier) {
		final Binder dup = duplicate();
		dup.interactionSupplier = (Supplier) interactionSupplier;
		return (Binder) dup;
	}

	@Override
	public  Binder toProduce(final Supplier cmdCreation) {
		return toProduce(i -> cmdCreation.get());
	}


	@Override
	public  Binder toProduce(final Function cmdCreation) {
		final Binder dup = duplicate();
		dup.cmdProducer = (Function) cmdCreation;
		return (Binder) dup;
	}
}