Changed zoom/pan of image editor to use scrollPane, also other small code tweaks in a few places.

This commit is contained in:
Brendan Robert 2014-12-15 20:59:38 -06:00
parent dee30787b4
commit ef905a7457
11 changed files with 87 additions and 154 deletions

View File

@ -54,11 +54,8 @@ public class Application extends javafx.application.Application {
throw new RuntimeException(exception);
}
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(final WindowEvent t) {
t.consume();
}
primaryStage.setOnCloseRequest((final WindowEvent t) -> {
t.consume();
});
primaryStage.show();
}

View File

@ -1,6 +1,6 @@
package org.badvision.outlaweditor;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import org.badvision.outlaweditor.data.DataObserver;
import org.badvision.outlaweditor.data.DataProducer;
import org.badvision.outlaweditor.data.xml.Script;
@ -28,7 +28,7 @@ public abstract class Editor<T, D> implements DataObserver<T> {
abstract public void showShiftUI();
abstract public void buildEditorUI(AnchorPane tileEditorAnchorPane);
abstract public void buildEditorUI(Pane targetPane);
abstract public void unregister();

View File

@ -21,13 +21,13 @@ public abstract class ImageEditor extends Editor<Image, ImageEditor.DrawMode> {
abstract public void buildPatternSelector(Menu tilePatternMenu);
public abstract void scrollBy(int deltaX, int deltaY);
public abstract void togglePanZoom();
public abstract void zoomIn();
public abstract void zoomOut();
public abstract double getZoomScale();
public abstract void exportImage();

View File

@ -19,7 +19,7 @@ import javafx.scene.input.Clipboard;
import javafx.scene.input.DataFormat;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
@ -37,7 +37,7 @@ import org.badvision.outlaweditor.ui.ToolType;
*/
public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventHandler<MouseEvent> {
AnchorPane anchorPane;
Pane anchorPane;
Canvas drawCanvas;
private Tile currentTile;
int posX = 0;
@ -80,7 +80,7 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
}
@Override
public void buildEditorUI(AnchorPane tileEditorAnchorPane) {
public void buildEditorUI(Pane tileEditorAnchorPane) {
anchorPane = tileEditorAnchorPane;
initCanvas();
redraw();

View File

@ -14,7 +14,7 @@ import javafx.scene.image.WritableImage;
import javafx.scene.input.Clipboard;
import javafx.scene.input.DataFormat;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import org.badvision.outlaweditor.Application;
@ -36,7 +36,7 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
public boolean hiBitMatters = true;
protected DrawMode currentDrawMode = DrawMode.Pencil1px;
protected WritableImage currentImage;
protected AnchorPane anchorPane;
protected Pane anchorPane;
protected ImageView screen;
protected int posX = 0;
protected int posY = 0;
@ -49,7 +49,7 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
}
@Override
public void buildEditorUI(AnchorPane editorAnchorPane) {
public void buildEditorUI(Pane editorAnchorPane) {
anchorPane = editorAnchorPane;
redraw();
screen = new ImageView(currentImage);
@ -105,15 +105,8 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
public void redraw() {
System.out.println("Redraw " + getPlatform().name());
currentImage = getPlatform().imageRenderer.renderImage(currentImage, getImageData(), getWidth(), getHeight());
fixPanArrows();
}
public void fixPanArrows() {
anchorPane.getChildren().get(1).setLayoutX((anchorPane.getWidth() - 30) / 2);
anchorPane.getChildren().get(2).setLayoutY((anchorPane.getHeight() - 30) / 2);
anchorPane.getChildren().get(3).setLayoutX((anchorPane.getWidth() - 30) / 2);
anchorPane.getChildren().get(4).setLayoutY((anchorPane.getHeight() - 30) / 2);
}
private byte[] imageData = null;
public byte[] getImageData() {
@ -146,7 +139,7 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
setData(data);
redraw();
}
@Override
public void togglePanZoom() {
anchorPane.getChildren().stream().filter((n) -> !(n == screen)).forEach((n) -> {
@ -154,16 +147,6 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
});
}
@Override
public void scrollBy(int deltaX, int deltaY) {
posX += deltaX * 20;
posY += deltaY * 20;
posX = Math.max(0, posX);
posY = Math.max(0, posY);
updatePanTranslation();
redraw();
}
@Override
public void zoomOut() {
if (zoom <= 1) {
@ -182,30 +165,14 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
}
}
private void zoom(double delta) {
double oldZoom = zoom;
zoom += delta;
zoom = Math.min(Math.max(0.15, zoom), 4.0);
// double left = mapEditorScroll.getHvalue();
// double top = mapEditorScroll.getVvalue();
//
// double pointerX = t.getX();
// double pointerY = t.getY();
//
double ratio = zoom / oldZoom;
//
// double newLeft = (left + pointerX) * ratio - pointerX;
// double newTop = (top + pointerY) * ratio - pointerY;
// Scale the image and move it so the upper-left corner is still in the right place.
screen.setScaleX(zoom);
screen.setScaleY(zoom);
updatePanTranslation();
redraw();
@Override
public double getZoomScale() {
return zoom;
}
public void updatePanTranslation() {
screen.setTranslateX((posX - getWidth()*7) * (zoom-1));
screen.setTranslateY((posY - getHeight()) * (zoom-1));
private void zoom(double delta) {
zoom += delta;
zoom = Math.min(Math.max(0.15, zoom), 4.0);
}
@Override
@ -402,8 +369,8 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
}
if (Clipboard.getSystemClipboard().hasContent(DataFormat.IMAGE)) {
javafx.scene.image.Image image = Clipboard.getSystemClipboard().getImage();
importImage(image);
importImage(image);
}
}
//selection/map/2/x1/0/y1/0/x2/19/y2/11
@ -443,7 +410,7 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
private void importImage(javafx.scene.image.Image image) {
ImageDitherEngine ditherEngine = new ImageDitherEngine(getPlatform());
ditherEngine.setTargetCoordinates(0,0);
ditherEngine.setTargetCoordinates(0, 0);
UIAction.openImageConversionModal(image, ditherEngine, getWidth(), getHeight(), this::setDataAndRedraw);
}
@ -469,11 +436,9 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
if (out == null) {
return;
}
try {
FileOutputStream outStream = new FileOutputStream(out);
try (FileOutputStream outStream = new FileOutputStream(out)) {
outStream.write(output);
outStream.flush();
outStream.close();
} catch (IOException ex) {
Logger.getLogger(AppleImageEditor.class.getName()).log(Level.SEVERE, null, ex);
}

View File

@ -6,7 +6,7 @@ import javafx.scene.control.Menu;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
@ -34,7 +34,7 @@ public class AppleTileEditor extends TileEditor {
}
@Override
public void buildEditorUI(AnchorPane tileEditorAnchorPane) {
public void buildEditorUI(Pane tileEditorAnchorPane) {
grid = new Rectangle[14][16];
gridGroup = new Group();
for (int y = 0; y < 16; y++) {
@ -42,17 +42,11 @@ public class AppleTileEditor extends TileEditor {
final int xx = x;
final int yy = y;
Rectangle rect = new Rectangle(zoom * x + 5, zoom * y + 5, zoom - 2, zoom - 2);
rect.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
performDragAction((int) (t.getX() / zoom), (int) (t.getY() / zoom));
}
rect.setOnMouseDragged((MouseEvent t) -> {
performDragAction((int) (t.getX() / zoom), (int) (t.getY() / zoom));
});
rect.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
handleMouse(t, xx, yy);
}
rect.setOnMousePressed((MouseEvent t) -> {
handleMouse(t, xx, yy);
});
grid[x][y] = rect;
gridGroup.getChildren().add(rect);
@ -146,11 +140,8 @@ public class AppleTileEditor extends TileEditor {
@Override
public void buildPatternSelector(Menu tilePatternMenu) {
FillPattern.buildMenu(tilePatternMenu, new DataObserver<FillPattern>() {
@Override
public void observedObjectChanged(FillPattern object) {
changeCurrentPattern(object);
}
FillPattern.buildMenu(tilePatternMenu, (FillPattern object) -> {
changeCurrentPattern(object);
});
}

View File

@ -1,18 +1,16 @@
package org.badvision.outlaweditor.apple.dhgr;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.control.Menu;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import org.badvision.outlaweditor.Platform;
import org.badvision.outlaweditor.TileEditor;
import org.badvision.outlaweditor.data.DataObserver;
import org.badvision.outlaweditor.data.xml.Tile;
import org.badvision.outlaweditor.data.TileUtils;
@ -34,7 +32,7 @@ public class AppleDHGRTileEditor extends TileEditor {
}
@Override
public void buildEditorUI(AnchorPane tileEditorAnchorPane) {
public void buildEditorUI(Pane tileEditorAnchorPane) {
grid = new Rectangle[28][16];
gridGroup = new Group();
for (int y = 0; y < 16; y++) {
@ -42,19 +40,13 @@ public class AppleDHGRTileEditor extends TileEditor {
final int xx = x;
final int yy = y;
Rectangle rect = new Rectangle((zoom/2) * x + 5, zoom * y + 5, zoom/2 - 2, zoom - 2);
rect.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
performDragAction((int) (t.getX() / (zoom/2)), (int) (t.getY() / zoom));
}
rect.setOnMouseDragged((MouseEvent t) -> {
performDragAction((int) (t.getX() / (zoom/2)), (int) (t.getY() / zoom));
});
rect.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
handleMouse(t, xx, yy);
lastActionX=-1;
lastActionY=-1;
}
rect.setOnMousePressed((MouseEvent t) -> {
handleMouse(t, xx, yy);
lastActionX=-1;
lastActionY=-1;
});
grid[x][y] = rect;
gridGroup.getChildren().add(rect);
@ -145,11 +137,8 @@ public class AppleDHGRTileEditor extends TileEditor {
@Override
public void buildPatternSelector(Menu tilePatternMenu) {
FillPattern.buildMenu(tilePatternMenu, new DataObserver<FillPattern>() {
@Override
public void observedObjectChanged(FillPattern object) {
changeCurrentPattern(object);
}
FillPattern.buildMenu(tilePatternMenu, (FillPattern object) -> {
changeCurrentPattern(object);
});
}

View File

@ -2,9 +2,10 @@ package org.badvision.outlaweditor.ui;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
import javafx.scene.Group;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Menu;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import org.badvision.outlaweditor.Editor;
@ -20,6 +21,12 @@ public abstract class ImageEditorTabController {
protected TextField imageCategoryField; // Value injected by FXMLLoader
@FXML // fx:id="imageEditorAnchorPane"
protected AnchorPane imageEditorAnchorPane; // Value injected by FXMLLoader
@FXML
protected ScrollPane imageEditorScrollPane;
@FXML
protected Group imageEditorZoomGroup;
@FXML
protected AnchorPane imageEditorScrollAnchorPane;
@FXML // fx:id="imageHeightField"
protected TextField imageHeightField; // Value injected by FXMLLoader
@FXML // fx:id="imageNameField"
@ -40,6 +47,9 @@ public abstract class ImageEditorTabController {
assert imagePatternMenu != null : "fx:id=\"imagePatternMenu\" was not injected: check your FXML file 'ApplicationUI.fxml'.";
assert imageSelector != null : "fx:id=\"imageSelector\" was not injected: check your FXML file 'ApplicationUI.fxml'.";
assert imageWidthField != null : "fx:id=\"imageWidthField\" was not injected: check your FXML file 'ApplicationUI.fxml'.";
assert imageEditorScrollPane != null : "fx:id\"imageEditorScrollPane\" was not injected: check your FXML file 'ApplicationUI.fxml'";
assert imageEditorZoomGroup != null : "fx:id\"imageEditorZoomGroup\" was not injected: check your FXML file 'ApplicationUI.fxml'";
assert imageEditorScrollAnchorPane != null : "fx:id\"imageEditorScrollAnchorPane\" was not injected: check your FXML file 'ApplicationUI.fxml'";
}
abstract public void rebuildImageSelector();
@ -95,21 +105,6 @@ public abstract class ImageEditorTabController {
@FXML
abstract public void onImageSelected(ActionEvent event);
// Handler for Button[Button[id=null, styleClass=button moveButton]] onAction
@FXML
abstract public void scrollImageDown(ActionEvent event);
// Handler for Button[Button[id=null, styleClass=button moveButton]] onAction
@FXML
abstract public void scrollImageLeft(ActionEvent event);
// Handler for Button[Button[id=null, styleClass=button moveButton]] onAction
@FXML
abstract public void scrollImageRight(ActionEvent event);
// Handler for Button[Button[id=null, styleClass=button moveButton]] onAction
@FXML
abstract public void scrollImageUp(ActionEvent event);
@FXML
abstract public void imageDraw5BitMode(ActionEvent event);

View File

@ -139,7 +139,11 @@ public class UIAction {
}
public static void quit() {
confirm("Quit? Are you sure?", Platform::exit, null);
confirm("Quit? Are you sure?", UIAction::quitWithoutConfirming, null);
}
public static void quitWithoutConfirming() {
Platform.runLater(Platform::exit);
}
static Image badImage;

View File

@ -113,6 +113,7 @@ public class ImageEditorTabControllerImpl extends ImageEditorTabController {
public void imageZoomIn(ActionEvent event) {
if (currentImageEditor != null) {
currentImageEditor.zoomIn();
updateScrollAreaWithScale(currentImageEditor.getZoomScale());
}
}
@ -120,6 +121,7 @@ public class ImageEditorTabControllerImpl extends ImageEditorTabController {
public void imageZoomOut(ActionEvent event) {
if (currentImageEditor != null) {
currentImageEditor.zoomOut();
updateScrollAreaWithScale(currentImageEditor.getZoomScale());
}
}
@ -162,34 +164,6 @@ public class ImageEditorTabControllerImpl extends ImageEditorTabController {
setCurrentImage(imageSelector.getSelectionModel().getSelectedItem());
}
@Override
public void scrollImageDown(ActionEvent event) {
if (currentImageEditor != null) {
currentImageEditor.scrollBy(0, 1);
}
}
@Override
public void scrollImageLeft(ActionEvent event) {
if (currentImageEditor != null) {
currentImageEditor.scrollBy(-1, 0);
}
}
@Override
public void scrollImageRight(ActionEvent event) {
if (currentImageEditor != null) {
currentImageEditor.scrollBy(1, 0);
}
}
@Override
public void scrollImageUp(ActionEvent event) {
if (currentImageEditor != null) {
currentImageEditor.scrollBy(0, -1);
}
}
private void setCurrentImage(Image i) {
if (currentImage != null && currentImage.equals(i)) {
return;
@ -229,7 +203,7 @@ public class ImageEditorTabControllerImpl extends ImageEditorTabController {
Logger.getLogger(ApplicationUIControllerImpl.class.getName()).log(Level.SEVERE, null, ex);
}
currentImageEditor.setEntity(i);
currentImageEditor.buildEditorUI(imageEditorAnchorPane);
currentImageEditor.buildEditorUI(imageEditorScrollAnchorPane);
currentImageEditor.buildPatternSelector(imagePatternMenu);
}
}
@ -245,4 +219,13 @@ public class ImageEditorTabControllerImpl extends ImageEditorTabController {
imageSelector.getItems().addAll(Application.gameData.getImage());
imageSelector.getSelectionModel().select(i);
}
private void updateScrollAreaWithScale(double zoomScale) {
double hval = imageEditorScrollPane.getHvalue();
double vval = imageEditorScrollPane.getVvalue();
imageEditorZoomGroup.setScaleX(zoomScale);
imageEditorZoomGroup.setScaleY(zoomScale);
imageEditorScrollPane.setHvalue(hval);
imageEditorScrollPane.setVvalue(vval);
}
}

View File

@ -6,14 +6,14 @@
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="tilesTab" minHeight="0.0" minWidth="0.0" prefHeight="420.0" prefWidth="677.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.badvision.outlaweditor.ui.impl.ImageEditorTabControllerImpl">
<AnchorPane id="tilesTab" minHeight="0.0" minWidth="0.0" prefHeight="420.0" prefWidth="677.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.badvision.outlaweditor.ui.impl.ImageEditorTabControllerImpl">
<children>
<VBox prefHeight="420.0000999999975" prefWidth="677.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<ToolBar prefWidth="686.0">
<items>
<Label text="Image:" />
<ComboBox id="tileSelect" fx:id="imageSelector" onAction="#onImageSelected"/>
<ComboBox id="tileSelect" fx:id="imageSelector" onAction="#onImageSelected" />
<Button mnemonicParsing="false" onAction="#onImageCreatePressed" text="Create new" />
<Button mnemonicParsing="false" onAction="#onImageClonePressed" text="Clone" />
<Button mnemonicParsing="false" onAction="#onImageExportPressed" text="Export" />
@ -52,12 +52,21 @@
</AnchorPane>
<AnchorPane id="mapEditorAnchorPane" fx:id="imageEditorAnchorPane" prefHeight="389.0" prefWidth="477.0" HBox.hgrow="ALWAYS">
<children>
<Button layoutX="236.0" mnemonicParsing="false" onAction="#scrollImageUp" styleClass="moveButton" text="Up" AnchorPane.topAnchor="5.0" />
<Button layoutY="185.0" mnemonicParsing="false" onAction="#scrollImageLeft" rotate="270.0" styleClass="moveButton" text="Left" AnchorPane.leftAnchor="-20.0" />
<Button layoutX="236.0" mnemonicParsing="false" onAction="#scrollImageDown" rotate="180.0" styleClass="moveButton" text="Down" AnchorPane.bottomAnchor="5.0" />
<Button layoutY="175.0" mnemonicParsing="false" onAction="#scrollImageRight" rotate="90.0" styleClass="moveButton" text="Right" AnchorPane.rightAnchor="-15.0" />
<Button mnemonicParsing="false" onAction="#imageZoomIn" styleClass="zoomInButton" text="+" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="5.0" />
<Button mnemonicParsing="false" onAction="#imageZoomOut" prefHeight="23.999908447265625" styleClass="zoomOutButton" text="-" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="30.0" />
<ScrollPane fx:id="imageEditorScrollPane" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<content>
<Group>
<children>
<Group fx:id="imageEditorZoomGroup">
<children>
<AnchorPane fx:id="imageEditorScrollAnchorPane" prefHeight="354.0" prefWidth="446.0" />
</children>
</Group>
</children>
</Group>
</content>
</ScrollPane>
<Button layoutX="433.0" layoutY="5.0" mnemonicParsing="false" onAction="#imageZoomIn" styleClass="zoomInButton" text="+" AnchorPane.rightAnchor="18.0" AnchorPane.topAnchor="5.0" />
<Button layoutX="435.0" layoutY="37.0" mnemonicParsing="false" onAction="#imageZoomOut" prefHeight="23.999908447265625" styleClass="zoomOutButton" text="-" AnchorPane.rightAnchor="18.0" AnchorPane.topAnchor="37.0" />
</children>
</AnchorPane>
</children>
@ -65,4 +74,4 @@
</children>
</VBox>
</children>
</AnchorPane>
</AnchorPane>