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

io.github.palexdev.mfxcore.utils.NodeMover Maven / Gradle / Ivy

There is a newer version: 11.26.0
Show newest version
/*
 * Copyright (C) 2024 Parisi Alessandro - [email protected]
 * This file is part of MaterialFX (https://github.com/palexdev/MaterialFX)
 *
 * MaterialFX is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 3 of the License,
 * or (at your option) any later version.
 *
 * MaterialFX 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with MaterialFX. If not, see .
 */

package io.github.palexdev.mfxcore.utils;

import io.github.palexdev.mfxcore.base.TriConsumer;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;

// TODO documentation
public class NodeMover {
	//================================================================================
	// Properties
	//================================================================================
	protected N node;

	private EventHandler draggedHandler = this::handleDragged;
	private EventHandler pressedHandler = this::handlePressed;
	private EventHandler movedHandler = this::handleMoved;
	private EventHandler releasedHandler = this::handleReleased;
	private EventHandler keyHandler = this::handleKeyPressed;
	private TriConsumer moveHandler;

	protected double clickedX;
	protected double clickedY;
	protected double translateX;
	protected double translateY;

	//================================================================================
	// Constructors
	//================================================================================
	public NodeMover(N node) {
		this(
			node,
			(n, x, y) -> {
				n.setTranslateX(x);
				n.setTranslateY(y);
			}
		);
	}

	public NodeMover(N node, TriConsumer moveHandler) {
		this.node = node;
		this.moveHandler = moveHandler;
	}

	public static  NodeMover install(T node) {
		return new NodeMover<>(node).install();
	}

	//================================================================================
	// Methods
	//================================================================================
	public NodeMover install() {
		node.addEventFilter(MouseEvent.MOUSE_PRESSED, pressedHandler);
		node.addEventFilter(MouseEvent.MOUSE_DRAGGED, draggedHandler);
		node.addEventFilter(MouseEvent.MOUSE_MOVED, movedHandler);
		node.addEventFilter(MouseEvent.MOUSE_RELEASED, releasedHandler);
		node.addEventFilter(KeyEvent.KEY_PRESSED, keyHandler);
		return this;
	}

	public void uninstall() {
		node.removeEventFilter(MouseEvent.MOUSE_PRESSED, pressedHandler);
		node.removeEventFilter(MouseEvent.MOUSE_DRAGGED, draggedHandler);
		node.removeEventFilter(MouseEvent.MOUSE_MOVED, movedHandler);
		node.removeEventFilter(MouseEvent.MOUSE_RELEASED, releasedHandler);
		node.removeEventFilter(KeyEvent.KEY_PRESSED, keyHandler);
	}

	public void dispose() {
		uninstall();
		handleReleased(null);
		pressedHandler = null;
		draggedHandler = null;
		movedHandler = null;
		releasedHandler = null;
		keyHandler = null;
		moveHandler = null;
		node = null;
	}

	protected void handleDragged(MouseEvent event) {
		double deltaX = event.getSceneX() - clickedX;
		double deltaY = event.getSceneY() - clickedY;
		moveHandler.accept(node, translateX + deltaX, translateY + deltaY);
	}

	protected void handlePressed(MouseEvent event) {
		node.requestFocus();
		clickedX = event.getSceneX();
		clickedY = event.getSceneY();
		translateX = node.getTranslateX();
		translateY = node.getTranslateY();
		node.setCursor(Cursor.CLOSED_HAND);
		consume(event);
	}

	protected void handleMoved(MouseEvent event) {
		node.setCursor(Cursor.OPEN_HAND);
	}

	protected void handleReleased(MouseEvent event) {
		node.setCursor(Cursor.OPEN_HAND);
	}

	protected void handleKeyPressed(KeyEvent event) {
		if (event.getCode() == KeyCode.ESCAPE) {
			moveHandler.accept(node, translateX, translateY);
			triggerMouseRelease();
		}
	}

	protected void triggerMouseRelease() {
		Event.fireEvent(node, new MouseEvent(MouseEvent.MOUSE_RELEASED,
			0, 0, 0, 0, MouseButton.PRIMARY, 1,
			false, false, false, false, true, false, false, false, false, false, null));
	}

	protected void consume(MouseEvent event) {
		event.consume();
	}

	//================================================================================
	// Getters/Setters
	//================================================================================
	public TriConsumer getMoveHandler() {
		return moveHandler;
	}

	public NodeMover setMoveHandler(TriConsumer moveHandler) {
		this.moveHandler = moveHandler;
		return this;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy