package de.synolo.app.qs.editor; import de.synolo.lib.fw.utils.Logging; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; import javafx.scene.input.ScrollEvent; public class EditorControl { private EditorCanvas editor; private ItemFactory itemFactory; private double dragX, dragY, offsetX = 0, offsetY = 0; private DoubleProperty zoomProperty = new SimpleDoubleProperty(1.0); private DoubleProperty zoomFactorProperty = new SimpleDoubleProperty(0.05), maxZoomProperty = new SimpleDoubleProperty(10), minZoomProperty = new SimpleDoubleProperty(0.05); private ItemNode selectedNode = null; public EditorControl(EditorCanvas editor) { this.editor = editor; editor.setOnScroll(this::onScroll); editor.setOnMouseClicked(this::onMouseClicked); editor.setOnMousePressed(this::onMousePressed); editor.setOnMouseReleased(this::onMouseReleased); editor.setOnMouseDragged(this::onMouseDragged); } public DoubleProperty zoomProperty() { return this.zoomProperty; } public double getZoom() { return this.zoomProperty.get(); } public void setZoom(double zoom) { this.zoomProperty.set(zoom); } public DoubleProperty zoomFactorProperty() { return this.zoomFactorProperty; } public double getZoomFactor() { return this.zoomFactorProperty.get(); } public void setZoomFactor(double factor) { this.zoomFactorProperty.set(factor); } public DoubleProperty zoomMaxProperty() { return this.maxZoomProperty; } public double getZoomMax() { return this.maxZoomProperty.get(); } public void setZoomMax(double max) { this.maxZoomProperty.set(max); } public DoubleProperty zoomMinProperty() { return this.minZoomProperty; } public double getZoomMin() { return this.minZoomProperty.get(); } public void setZoomMin(double min) { this.minZoomProperty.set(min); } double getOffsetX() { return this.offsetX; } double getOffsetY() { return this.offsetY; } public double getWorldX(double screenX) { return (screenX / getZoom()) + this.offsetX; } public double getWorldY(double screenY) { return (screenY / getZoom()) + this.offsetY; } public double getScreenX(double worldX) { return (worldX - this.offsetX) * getZoom(); } public double getScreenY(double worldY) { return (worldY - this.offsetY) * getZoom(); } public EditorCanvas getEditor() { return this.editor; } public ItemFactory getItemFactory() { return this.itemFactory; } public void setItemFactory(ItemFactory factory) { this.itemFactory = factory; } private void onScroll(ScrollEvent e) { double scale = getZoom(); if(e.getDeltaY() > 0) { scale *= (1.0 + getZoomFactor()); }else { scale *= (1.0 - getZoomFactor()); } scale = scale >= getZoomMax() ? getZoomMax() : scale <= getZoomMin() ? getZoomMin() : scale; double xBefore = getWorldX(e.getX()), yBefore = getWorldY(e.getY()); setZoom(scale); double xAfter = getWorldX(e.getX()), yAfter = getWorldY(e.getY()); this.offsetX += (xBefore - xAfter); this.offsetY += (yBefore - yAfter); editor.paint(); } private void onMouseClicked(MouseEvent e) { if(e.isConsumed()) return; } private void onMousePressed(MouseEvent e) { if(e.getButton() == MouseButton.MIDDLE) { this.dragX = e.getX(); this.dragY = e.getY(); this.editor.setState(EditorState.PANNING); } double worldX = getWorldX(e.getX()), worldY = getWorldY(e.getY()); switch(this.editor.getState()) { case EDITING: break; case INSERTING: if(this.itemFactory != null) { EditorLayer layer = this.editor.getLayerSelectionModel().getSelectedItems().get(0); if(layer != null) { EditorItem item = this.itemFactory.createItem(); item.setSelected(true); this.selectedNode = item.nextNode(worldX, worldY); if(this.selectedNode != null) { this.editor.setState(EditorState.EDITING); } layer.getItems().add(item); System.out.println("add item"); }else { Logging.out.warn("No Layer selected!"); } } break; case PANNING: break; case ZOOMING: break; default: break; } } private void onMouseReleased(MouseEvent e) { EditorState state = EditorState.INSERTING; switch(this.editor.getState()) { case EDITING: case INSERTING: case PANNING: case ZOOMING: } this.editor.setState(state); this.selectedNode = null; } private void onMouseDragged(MouseEvent e) { double worldX = getWorldX(e.getX()), worldY = getWorldY(e.getY()); switch(this.editor.getState()) { case EDITING: if(this.selectedNode != null) { this.selectedNode.setX(worldX); this.selectedNode.setY(worldY); this.editor.paint(); } break; case INSERTING: break; case PANNING: break; case ZOOMING: break; default: break; } if(e.getButton() == MouseButton.MIDDLE) { this.offsetX -= (e.getX() - this.dragX) / getZoom(); this.offsetY -= (e.getY() - this.dragY) / getZoom(); this.dragX = e.getX(); this.dragY = e.getY(); this.editor.paint(); } } }