mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-12-26 19:29:27 +00:00
Merge branch 'master' of https://github.com/badvision/lawless-legends
This commit is contained in:
commit
b2b922aa7c
@ -16,14 +16,19 @@ import javafx.scene.Scene;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
import javafx.scene.effect.DropShadow;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.image.WritableImage;
|
||||
import javafx.scene.input.Clipboard;
|
||||
import javafx.scene.input.DataFormat;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
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.FillRule;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
import javafx.stage.Stage;
|
||||
import static org.badvision.outlaweditor.Application.currentPlatform;
|
||||
@ -33,6 +38,7 @@ import org.badvision.outlaweditor.data.xml.Map;
|
||||
import org.badvision.outlaweditor.data.xml.Script;
|
||||
import org.badvision.outlaweditor.data.xml.Tile;
|
||||
import org.badvision.outlaweditor.ui.ToolType;
|
||||
import org.badvision.outlaweditor.ui.UIAction;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -75,6 +81,10 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
|
||||
@Override
|
||||
public void setDrawMode(DrawMode drawMode) {
|
||||
this.drawMode = drawMode;
|
||||
if (drawMode == DrawMode.Eraser) {
|
||||
ImageCursor cursor = new ImageCursor(new Image("images/eraser.png"));
|
||||
drawCanvas.setCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -85,10 +95,24 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
|
||||
@Override
|
||||
public void buildEditorUI(Pane tileEditorAnchorPane) {
|
||||
anchorPane = tileEditorAnchorPane;
|
||||
Application.getPrimaryStage().getScene().addEventHandler(KeyEvent.KEY_PRESSED, this::keyPressed);
|
||||
initCanvas();
|
||||
redraw();
|
||||
}
|
||||
|
||||
private void keyPressed(KeyEvent e) {
|
||||
if (e.isControlDown() && e.getCode() == KeyCode.SPACE) {
|
||||
e.consume();
|
||||
String category = null;
|
||||
if (currentTile != null) {
|
||||
category = currentTile.getCategory();
|
||||
}
|
||||
if (this.equals(Application.getInstance().getController().getVisibleEditor())) {
|
||||
UIAction.showTileSelectModal((AnchorPane) anchorPane, category, this::setCurrentTile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void initCanvas() {
|
||||
if (drawCanvas != null) {
|
||||
anchorPane.getChildren().remove(drawCanvas);
|
||||
@ -218,7 +242,7 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
|
||||
}
|
||||
|
||||
private synchronized void doRedraw() {
|
||||
drawCanvas.getGraphicsContext2D().clearRect(0, 0, drawCanvas.getWidth(), drawCanvas.getHeight());
|
||||
clearCanvas();
|
||||
int cols = (int) (drawCanvas.getWidth() / tileWidth);
|
||||
int rows = (int) (drawCanvas.getHeight() / tileHeight);
|
||||
for (int x = 0; x <= cols; x++) {
|
||||
@ -238,13 +262,27 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
|
||||
anchorPane.getChildren().get(4).setLayoutY((drawCanvas.getHeight() - 30) / 2);
|
||||
}
|
||||
|
||||
public void clearCanvas() {
|
||||
boolean oddEvenColumn = false;
|
||||
boolean oddEven;
|
||||
for (int x=0; x < drawCanvas.getWidth(); x += 10) {
|
||||
oddEven = oddEvenColumn;
|
||||
for (int y=0; y < drawCanvas.getHeight(); y += 10) {
|
||||
drawCanvas.getGraphicsContext2D().setFill(oddEven ? Color.BLACK : Color.NAVY);
|
||||
drawCanvas.getGraphicsContext2D().fillRect(x, y, 10, 10);
|
||||
oddEven = !oddEven;
|
||||
}
|
||||
oddEvenColumn = !oddEvenColumn;
|
||||
}
|
||||
}
|
||||
|
||||
private void doDraw(int x, int y, Tile tile) {
|
||||
double xx = x * tileWidth;
|
||||
double yy = y * tileHeight;
|
||||
if (tile != null) {
|
||||
drawCanvas.getGraphicsContext2D().drawImage(TileUtils.getImage(tile, currentPlatform), xx, yy, tileWidth, tileHeight);
|
||||
} else {
|
||||
drawCanvas.getGraphicsContext2D().clearRect(xx, yy, tileWidth, tileHeight);
|
||||
// drawCanvas.getGraphicsContext2D().clearRect(xx, yy, tileWidth, tileHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@ -342,6 +380,7 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
|
||||
drawCanvas.heightProperty().unbind();
|
||||
anchorPane.getChildren().remove(drawCanvas);
|
||||
currentMap.updateBackingMap();
|
||||
Application.getPrimaryStage().getScene().removeEventHandler(KeyEvent.KEY_PRESSED, this::keyPressed);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -353,11 +392,16 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
|
||||
|
||||
/**
|
||||
* @param currentTile the currentTile to set
|
||||
* @return Same tile (necessary for callback support)
|
||||
*/
|
||||
public void setCurrentTile(Tile currentTile) {
|
||||
public Tile setCurrentTile(Tile currentTile) {
|
||||
if (drawMode == DrawMode.Eraser) {
|
||||
drawMode = DrawMode.Pencil1px;
|
||||
}
|
||||
this.currentTile = currentTile;
|
||||
ImageCursor cursor = new ImageCursor(TileUtils.getImage(currentTile, currentPlatform), 2, 2);
|
||||
drawCanvas.setCursor(cursor);
|
||||
return currentTile;
|
||||
}
|
||||
|
||||
public void showPreview() {
|
||||
@ -406,7 +450,7 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
|
||||
|
||||
public static enum DrawMode {
|
||||
|
||||
Pencil1px, Pencil3px, Pencil5px, FilledRect
|
||||
Pencil1px, Pencil3px, Pencil5px, FilledRect, Eraser
|
||||
};
|
||||
|
||||
public void plot(final int x, final int y, final Tile t) {
|
||||
@ -488,7 +532,7 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
|
||||
|
||||
@Override
|
||||
public void handle(MouseEvent t) {
|
||||
if (getCurrentTile() == null) {
|
||||
if (getCurrentTile() == null && drawMode != DrawMode.Eraser) {
|
||||
System.out.println("No tile selected, ignoring");
|
||||
return;
|
||||
}
|
||||
@ -504,6 +548,14 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
|
||||
lastDrawMode = drawMode;
|
||||
lastTile = getCurrentTile();
|
||||
switch (drawMode) {
|
||||
case Eraser: {
|
||||
if (canSkip) {
|
||||
return;
|
||||
}
|
||||
plot(x,y,null);
|
||||
redraw();
|
||||
break;
|
||||
}
|
||||
case Pencil1px:
|
||||
if (canSkip) {
|
||||
return;
|
||||
|
@ -56,6 +56,9 @@ public abstract class MapEditorTabController {
|
||||
@FXML
|
||||
protected Button scriptEraseTool;
|
||||
|
||||
@FXML
|
||||
abstract public void mapEraser(ActionEvent event);
|
||||
|
||||
@FXML
|
||||
abstract public void mapDraw1(ActionEvent event);
|
||||
|
||||
|
@ -10,32 +10,53 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
import javafx.animation.FadeTransition;
|
||||
import javafx.animation.ScaleTransition;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Menu;
|
||||
import javafx.scene.control.MenuBar;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.effect.BlurType;
|
||||
import javafx.scene.effect.DropShadow;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.image.WritableImage;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.Background;
|
||||
import javafx.scene.layout.BackgroundFill;
|
||||
import javafx.scene.layout.CornerRadii;
|
||||
import javafx.scene.layout.HBoxBuilder;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.VBoxBuilder;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Callback;
|
||||
import javafx.util.Duration;
|
||||
import javax.xml.bind.JAXB;
|
||||
import org.badvision.outlaweditor.Application;
|
||||
import static org.badvision.outlaweditor.Application.currentPlatform;
|
||||
import org.badvision.outlaweditor.FileUtils;
|
||||
import org.badvision.outlaweditor.MythosEditor;
|
||||
import org.badvision.outlaweditor.apple.ImageDitherEngine;
|
||||
import org.badvision.outlaweditor.data.TileUtils;
|
||||
import org.badvision.outlaweditor.data.TilesetUtils;
|
||||
import org.badvision.outlaweditor.data.xml.GameData;
|
||||
import org.badvision.outlaweditor.data.xml.Script;
|
||||
import org.badvision.outlaweditor.data.xml.Tile;
|
||||
import org.badvision.outlaweditor.ui.impl.ImageConversionWizardController;
|
||||
|
||||
/**
|
||||
@ -141,7 +162,7 @@ public class UIAction {
|
||||
public static void quit() {
|
||||
confirm("Quit? Are you sure?", UIAction::quitWithoutConfirming, null);
|
||||
}
|
||||
|
||||
|
||||
public static void quitWithoutConfirming() {
|
||||
Platform.runLater(Platform::exit);
|
||||
}
|
||||
@ -212,7 +233,7 @@ public class UIAction {
|
||||
editor.show();
|
||||
return script;
|
||||
}
|
||||
|
||||
|
||||
public static ImageConversionWizardController openImageConversionModal(Image image, ImageDitherEngine ditherEngine, int targetWidth, int targetHeight, ImageConversionPostAction postAction) {
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(UIAction.class.getResource("/imageConversionWizard.fxml"));
|
||||
try {
|
||||
@ -230,6 +251,106 @@ public class UIAction {
|
||||
return controller;
|
||||
} catch (IOException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final int GRID_SPACING = 7;
|
||||
public static final int MAX_TILES_PER_ROW = 16;
|
||||
public static AnchorPane currentTileSelector;
|
||||
|
||||
public static void showTileSelectModal(Pane anchorPane, String category, Callback<Tile,?> callback) {
|
||||
if (currentTileSelector != null) {
|
||||
return;
|
||||
}
|
||||
currentTileSelector = new AnchorPane();
|
||||
|
||||
int TILE_WIDTH = Application.currentPlatform.tileRenderer.getWidth();
|
||||
int TILE_HEIGHT = Application.currentPlatform.tileRenderer.getHeight();
|
||||
|
||||
List<Tile> tiles = Application.gameData.getTile().stream().filter((Tile t) -> {
|
||||
return category == null || t.getCategory().equals(category);
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
int tilesPerRow = (int) Math.min(tiles.size(), Math.min(MAX_TILES_PER_ROW, anchorPane.getWidth() / (TILE_WIDTH + GRID_SPACING)));
|
||||
int numRows = (tiles.size() + tilesPerRow - 1) / tilesPerRow;
|
||||
int prefWidth = tilesPerRow * (TILE_WIDTH + GRID_SPACING) + GRID_SPACING;
|
||||
currentTileSelector.setPrefWidth(prefWidth);
|
||||
currentTileSelector.setPrefHeight(Math.min(numRows * (TILE_HEIGHT + GRID_SPACING) + GRID_SPACING, prefWidth));
|
||||
for (int i = 0; i < tiles.size(); i++) {
|
||||
final Tile tile = tiles.get(i);
|
||||
ImageView tileIcon = new ImageView(TileUtils.getImage(tile, currentPlatform));
|
||||
currentTileSelector.getChildren().add(tileIcon);
|
||||
tileIcon.setOnMouseClicked((e) -> {
|
||||
e.consume();
|
||||
callback.call(tile);
|
||||
closeCurrentTileSelector();
|
||||
});
|
||||
tileIcon.setOnMouseEntered((e) -> {
|
||||
tileIcon.setEffect(new DropShadow(BlurType.GAUSSIAN, Color.CORNSILK, 5.0, 0.5, 0, 0));
|
||||
ScaleTransition st = new ScaleTransition(Duration.millis(150), tileIcon);
|
||||
st.setAutoReverse(false);
|
||||
st.setToX(1.25);
|
||||
st.setToY(1.25);
|
||||
st.play();
|
||||
});
|
||||
tileIcon.setOnMouseExited((e) -> {
|
||||
tileIcon.setEffect(null);
|
||||
ScaleTransition st = new ScaleTransition(Duration.millis(150), tileIcon);
|
||||
st.setAutoReverse(false);
|
||||
st.setToX(1);
|
||||
st.setToY(1);
|
||||
st.play();
|
||||
});
|
||||
tileIcon.setLayoutX(GRID_SPACING + (i % tilesPerRow) * (TILE_WIDTH + GRID_SPACING));
|
||||
tileIcon.setLayoutY(GRID_SPACING + (i / tilesPerRow) * (TILE_HEIGHT + GRID_SPACING));
|
||||
}
|
||||
currentTileSelector.setLayoutX((anchorPane.getWidth() - currentTileSelector.getPrefWidth()) / 2);
|
||||
currentTileSelector.setLayoutY((anchorPane.getHeight() - currentTileSelector.getPrefHeight()) / 2);
|
||||
currentTileSelector.setBackground(
|
||||
new Background(
|
||||
new BackgroundFill(
|
||||
new Color(0.7, 0.7, 0.9, 0.75),
|
||||
new CornerRadii(10.0),
|
||||
null)));
|
||||
currentTileSelector.setEffect(new DropShadow(5.0, 1.0, 1.0, Color.BLACK));
|
||||
anchorPane.getChildren().add(currentTileSelector);
|
||||
Application.getPrimaryStage().getScene().addEventHandler(KeyEvent.KEY_PRESSED, cancelTileSelectKeyHandler);
|
||||
Application.getPrimaryStage().getScene().addEventFilter(MouseEvent.MOUSE_PRESSED, cancelTileSelectMouseHandler);
|
||||
}
|
||||
|
||||
private static final EventHandler<MouseEvent> cancelTileSelectMouseHandler = (MouseEvent e) -> {
|
||||
if (! (e.getSource() instanceof ImageView)) {
|
||||
e.consume();
|
||||
}
|
||||
closeCurrentTileSelector();
|
||||
};
|
||||
|
||||
private static final EventHandler<KeyEvent> cancelTileSelectKeyHandler = (KeyEvent e) -> {
|
||||
if (e.getCode() == KeyCode.ESCAPE) {
|
||||
closeCurrentTileSelector();
|
||||
}
|
||||
};
|
||||
|
||||
public static void closeCurrentTileSelector() {
|
||||
Application.getPrimaryStage().getScene().removeEventHandler(KeyEvent.KEY_PRESSED, cancelTileSelectKeyHandler);
|
||||
Application.getPrimaryStage().getScene().removeEventFilter(MouseEvent.MOUSE_PRESSED, cancelTileSelectMouseHandler);
|
||||
|
||||
fadeOut(currentTileSelector, (ActionEvent ev) -> {
|
||||
if (currentTileSelector != null) {
|
||||
Pane parent = (Pane) currentTileSelector.getParent();
|
||||
parent.getChildren().remove(currentTileSelector);
|
||||
currentTileSelector = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void fadeOut(Node node, EventHandler<ActionEvent> callback) {
|
||||
FadeTransition ft = new FadeTransition(Duration.millis(250), node);
|
||||
ft.setFromValue(1.0);
|
||||
ft.setToValue(0.0);
|
||||
ft.setCycleCount(1);
|
||||
ft.setAutoReverse(false);
|
||||
ft.setOnFinished(callback);
|
||||
ft.play();
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,13 @@ public class MapEditorTabControllerImpl extends MapEditorTabController {
|
||||
final TransferHelper<Script> scriptDragDrop = new TransferHelper<>(Script.class);
|
||||
final TransferHelper<ToolType> toolDragDrop = new TransferHelper<>(ToolType.class);
|
||||
|
||||
@Override
|
||||
public void mapEraser(ActionEvent event) {
|
||||
if (getCurrentEditor() != null) {
|
||||
getCurrentEditor().setDrawMode(MapEditor.DrawMode.Eraser);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mapDraw1(ActionEvent event) {
|
||||
if (getCurrentEditor() != null) {
|
||||
@ -284,7 +291,7 @@ public class MapEditorTabControllerImpl extends MapEditorTabController {
|
||||
});
|
||||
toolDragDrop.registerDragSupport(scriptEraseTool, ToolType.ERASER);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void rebuildTileSelectors() {
|
||||
mapSelectTile.getItems().clear();
|
||||
|
@ -26,6 +26,7 @@
|
||||
<MenuItem mnemonicParsing="false" onAction="#mapDraw3" text="Radius 3" />
|
||||
<MenuItem mnemonicParsing="false" onAction="#mapDraw5" text="Radius 5" />
|
||||
<MenuItem mnemonicParsing="false" onAction="#mapDrawFilledRectMode" text="Filled Rectangle" />
|
||||
<MenuItem mnemonicParsing="false" onAction="#mapEraser" text="Eraser" />
|
||||
</items>
|
||||
</Menu>
|
||||
<MenuItem mnemonicParsing="false" onAction="#mapTogglePanZoom" text="Toggle pan/zoom controls" />
|
||||
|
Loading…
Reference in New Issue
Block a user