mirror of
https://github.com/badvision/lawless-legends.git
synced 2025-08-15 06:27:24 +00:00
Copy/paste support added to the Apple hi-res editor (as well as selection)
This commit is contained in:
@@ -111,13 +111,6 @@
|
|||||||
</build>
|
</build>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- <dependency>
|
|
||||||
<groupId>com.oracle</groupId>
|
|
||||||
<artifactId>javafx</artifactId>
|
|
||||||
<version>2</version>
|
|
||||||
<systemPath>${java.home}/lib/jfxrt.jar</systemPath>
|
|
||||||
<scope>system</scope>
|
|
||||||
</dependency>-->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javafx-packager</groupId>
|
<groupId>javafx-packager</groupId>
|
||||||
<artifactId>javafx-packager</artifactId>
|
<artifactId>javafx-packager</artifactId>
|
||||||
|
@@ -67,7 +67,7 @@ public abstract class Editor<T, D> implements DataObserver<T> {
|
|||||||
startY = Math.min(y1, y2);
|
startY = Math.min(y1, y2);
|
||||||
endX = Math.max(x1, x2);
|
endX = Math.max(x1, x2);
|
||||||
endY = Math.max(y1, y2);
|
endY = Math.max(y1, y2);
|
||||||
if (startX + startY + endX + endY == 0) {
|
if (startX + startY + endX + endY <= 0) {
|
||||||
selectInfo = null;
|
selectInfo = null;
|
||||||
} else {
|
} else {
|
||||||
selectInfo = "x1/" + startX + "/y1/" + startY + "/x2/" + endX + "/y2/" + endY;
|
selectInfo = "x1/" + startX + "/y1/" + startY + "/x2/" + endX + "/y2/" + endY;
|
||||||
@@ -79,7 +79,6 @@ public abstract class Editor<T, D> implements DataObserver<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String selectInfo;
|
String selectInfo;
|
||||||
|
|
||||||
public String getSelectionInfo() {
|
public String getSelectionInfo() {
|
||||||
if (selectInfo == null) {
|
if (selectInfo == null) {
|
||||||
return getSelectedAllInfo();
|
return getSelectedAllInfo();
|
||||||
|
@@ -23,7 +23,7 @@ public abstract class ImageEditor extends Editor<Image, ImageEditor.DrawMode> {
|
|||||||
|
|
||||||
public static enum DrawMode {
|
public static enum DrawMode {
|
||||||
|
|
||||||
Toggle, Pencil1px, Pencil3px, Pencil5px, Rectangle, Circle, Stamp
|
Toggle, Pencil1px, Pencil3px, Pencil5px, Rectangle, Circle, Stamp, Select
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract public EnumMap getState();
|
abstract public EnumMap getState();
|
||||||
|
@@ -7,7 +7,6 @@
|
|||||||
* ANY KIND, either express or implied. See the License for the specific language
|
* ANY KIND, either express or implied. See the License for the specific language
|
||||||
* governing permissions and limitations under the License.
|
* governing permissions and limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.badvision.outlaweditor.apple;
|
package org.badvision.outlaweditor.apple;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -55,7 +54,10 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
|
|||||||
protected double zoom = 1.0;
|
protected double zoom = 1.0;
|
||||||
protected int xScale = 2;
|
protected int xScale = 2;
|
||||||
protected int yScale = 2;
|
protected int yScale = 2;
|
||||||
public static enum StateVars{PATTERN, DRAW_MODE};
|
|
||||||
|
public static enum StateVars {
|
||||||
|
PATTERN, DRAW_MODE
|
||||||
|
};
|
||||||
|
|
||||||
public Platform getPlatform() {
|
public Platform getPlatform() {
|
||||||
return Platform.AppleII;
|
return Platform.AppleII;
|
||||||
@@ -66,7 +68,7 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
|
|||||||
super.onEntityUpdated();
|
super.onEntityUpdated();
|
||||||
data = null;
|
data = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void buildEditorUI(Pane editorAnchorPane) {
|
public void buildEditorUI(Pane editorAnchorPane) {
|
||||||
anchorPane = editorAnchorPane;
|
anchorPane = editorAnchorPane;
|
||||||
@@ -89,7 +91,9 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void changeCurrentPattern(FillPattern pattern) {
|
public void changeCurrentPattern(FillPattern pattern) {
|
||||||
if (pattern == null) return;
|
if (pattern == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
currentFillPattern = pattern.getBytePattern();
|
currentFillPattern = pattern.getBytePattern();
|
||||||
hiBitMatters = pattern.hiBitMatters;
|
hiBitMatters = pattern.hiBitMatters;
|
||||||
lastActionX = -1;
|
lastActionX = -1;
|
||||||
@@ -97,6 +101,7 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
|
|||||||
}
|
}
|
||||||
|
|
||||||
EnumMap<StateVars, Object> state = new EnumMap<>(StateVars.class);
|
EnumMap<StateVars, Object> state = new EnumMap<>(StateVars.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EnumMap getState() {
|
public EnumMap getState() {
|
||||||
return state;
|
return state;
|
||||||
@@ -113,17 +118,21 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
|
|||||||
state.put(StateVars.DRAW_MODE, currentDrawMode);
|
state.put(StateVars.DRAW_MODE, currentDrawMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDrawMode(DrawMode drawMode) {
|
public void setDrawMode(DrawMode drawMode) {
|
||||||
_setDrawMode(drawMode);
|
_setDrawMode(drawMode);
|
||||||
state.put(StateVars.DRAW_MODE, drawMode);
|
state.put(StateVars.DRAW_MODE, drawMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _setDrawMode(DrawMode drawMode) {
|
private void _setDrawMode(DrawMode drawMode) {
|
||||||
currentDrawMode = drawMode;
|
currentDrawMode = drawMode;
|
||||||
lastActionX = -1;
|
lastActionX = -1;
|
||||||
lastActionY = -1;
|
lastActionY = -1;
|
||||||
|
selectionFinished = false;
|
||||||
|
if (drawMode != DrawMode.Stamp) {
|
||||||
|
selectNone();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -152,6 +161,7 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
|
|||||||
}
|
}
|
||||||
|
|
||||||
PlatformData data = null;
|
PlatformData data = null;
|
||||||
|
|
||||||
public PlatformData getPlatformData() {
|
public PlatformData getPlatformData() {
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
data = getPlatformData(getPlatform());
|
data = getPlatformData(getPlatform());
|
||||||
@@ -162,7 +172,7 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
|
|||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getImageData() {
|
public byte[] getImageData() {
|
||||||
return getPlatformData().getValue();
|
return getPlatformData().getValue();
|
||||||
}
|
}
|
||||||
@@ -283,15 +293,28 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
|
|||||||
updateSelection(x, y);
|
updateSelection(x, y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case Select:
|
||||||
|
debounce = System.currentTimeMillis();
|
||||||
|
if (selectionFinished && !released) {
|
||||||
|
startSelection(x, y);
|
||||||
|
} else {
|
||||||
|
updateSelection(x, y);
|
||||||
|
}
|
||||||
|
selectionFinished = released;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
// observedObjectChanged(getEntity());
|
// observedObjectChanged(getEntity());
|
||||||
}
|
}
|
||||||
|
public boolean selectionFinished = false;
|
||||||
public static Rectangle selectRect = null;
|
public static Rectangle selectRect = null;
|
||||||
public int selectStartX = -1;
|
public int selectStartX = -1;
|
||||||
public int selectStartY = -1;
|
public int selectStartY = -1;
|
||||||
|
public int selectEndX = -1;
|
||||||
|
public int selectEndY = -1;
|
||||||
|
|
||||||
private void startSelection(int x, int y) {
|
private void startSelection(int x, int y) {
|
||||||
|
selectNone();
|
||||||
selectRect = new Rectangle(1, 1, Color.NAVY);
|
selectRect = new Rectangle(1, 1, Color.NAVY);
|
||||||
selectRect.setTranslateX(x * xScale);
|
selectRect.setTranslateX(x * xScale);
|
||||||
selectRect.setTranslateY(y * yScale);
|
selectRect.setTranslateY(y * yScale);
|
||||||
@@ -306,14 +329,22 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
|
|||||||
startSelection(x, y);
|
startSelection(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
double minX = Math.min(selectStartX, x) * xScale;
|
int startX = Math.min(selectStartX, x);
|
||||||
double minY = Math.min(selectStartY, y) * yScale;
|
int endX = Math.max(selectStartX, x);
|
||||||
double maxX = Math.max(selectStartX, x) * xScale;
|
int startY = Math.min(selectStartY, y);
|
||||||
double maxY = Math.max(selectStartY, y) * yScale;
|
int endY = Math.max(selectStartY, y);
|
||||||
selectRect.setTranslateX(minX);
|
|
||||||
selectRect.setTranslateY(minY);
|
selectStartX = startX;
|
||||||
selectRect.setWidth(maxX - minX);
|
selectStartY = startY;
|
||||||
selectRect.setHeight(maxY - minY);
|
selectEndX = endX;
|
||||||
|
selectEndY = endY;
|
||||||
|
|
||||||
|
selectRect.setTranslateX(startX * xScale);
|
||||||
|
selectRect.setTranslateY(startY * yScale);
|
||||||
|
selectRect.setWidth((endX - startX) * xScale);
|
||||||
|
selectRect.setHeight((endY - startY) * yScale);
|
||||||
|
|
||||||
|
setSelectionArea(selectStartX, selectStartY, selectEndX, selectEndY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillSelection(int x, int y) {
|
private void fillSelection(int x, int y) {
|
||||||
@@ -392,12 +423,14 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
|
|||||||
return getPlatformData(getPlatform()).getHeight();
|
return getPlatformData(getPlatform()).getHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] copyData = null;
|
||||||
@Override
|
@Override
|
||||||
public void copy() {
|
public void copy() {
|
||||||
java.util.Map<DataFormat, Object> clip = new HashMap<>();
|
java.util.Map<DataFormat, Object> clip = new HashMap<>();
|
||||||
clip.put(DataFormat.IMAGE, currentImage);
|
clip.put(DataFormat.IMAGE, currentImage);
|
||||||
clip.put(DataFormat.PLAIN_TEXT, "selection/image/" + Application.gameData.getImage().indexOf(getEntity()) + "/" + getSelectionInfo());
|
clip.put(DataFormat.PLAIN_TEXT, "selection/image/" + Application.gameData.getImage().indexOf(getEntity()) + "/" + getSelectionInfo());
|
||||||
Clipboard.getSystemClipboard().setContent(clip);
|
Clipboard.getSystemClipboard().setContent(clip);
|
||||||
|
copyData = Arrays.copyOf(getImageData(), getImageData().length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -416,6 +449,7 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
|
|||||||
//selection/map/2/x1/0/y1/0/x2/19/y2/11
|
//selection/map/2/x1/0/y1/0/x2/19/y2/11
|
||||||
|
|
||||||
public boolean pasteAppContent(String contentPath) {
|
public boolean pasteAppContent(String contentPath) {
|
||||||
|
trackState();
|
||||||
System.out.println("Clipboard >> " + contentPath);
|
System.out.println("Clipboard >> " + contentPath);
|
||||||
if (contentPath.startsWith("selection/map")) {
|
if (contentPath.startsWith("selection/map")) {
|
||||||
String[] bufferDetails = contentPath.substring(14).split("/");
|
String[] bufferDetails = contentPath.substring(14).split("/");
|
||||||
@@ -437,18 +471,65 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
|
|||||||
} else if (contentPath.startsWith("selection/image")) {
|
} else if (contentPath.startsWith("selection/image")) {
|
||||||
String[] bufferDetails = contentPath.substring(16).split("/");
|
String[] bufferDetails = contentPath.substring(16).split("/");
|
||||||
int imageNumber = Integer.parseInt(bufferDetails[0]);
|
int imageNumber = Integer.parseInt(bufferDetails[0]);
|
||||||
|
Image sourceImage = Application.gameData.getImage().get(imageNumber);
|
||||||
|
byte[] sourceData;
|
||||||
|
if (sourceImage.equals(getEntity())) {
|
||||||
|
sourceData = copyData;
|
||||||
|
} else {
|
||||||
|
PlatformData platformData = sourceImage.getDisplayData().stream().filter(d -> d.getPlatform().equals(getPlatform().name())).findFirst().orElse(null);
|
||||||
|
if (platformData == null) {
|
||||||
|
throw new NullPointerException("Unable to paste from source image, no matching platform data.");
|
||||||
|
}
|
||||||
|
sourceData = platformData.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
if ("all".equals(bufferDetails[1])) {
|
if ("all".equals(bufferDetails[1])) {
|
||||||
Image sourceImage = Application.gameData.getImage().get(imageNumber);
|
setData(Arrays.copyOf(sourceData, sourceData.length));
|
||||||
for (PlatformData data : sourceImage.getDisplayData()) {
|
redraw();
|
||||||
if (data.getPlatform().equals(getPlatform().toString())) {
|
return true;
|
||||||
setData(Arrays.copyOf(data.getValue(), data.getValue().length));
|
} else {
|
||||||
redraw();
|
int xStart = Integer.parseInt(bufferDetails[2]);
|
||||||
return true;
|
int yStart = Integer.parseInt(bufferDetails[4]);
|
||||||
|
int xEnd = Integer.parseInt(bufferDetails[6]);
|
||||||
|
int yEnd = Integer.parseInt(bufferDetails[8]);
|
||||||
|
byte[] targetData = getImageData();
|
||||||
|
int pasteX = lastActionX;
|
||||||
|
int pasteY = lastActionY;
|
||||||
|
// fix odd/even: Try to nudge left or right where it might work best.
|
||||||
|
if ((xStart%2) != pasteX %2) {
|
||||||
|
if (pasteX == 0 || pasteX % 7 > 3 || (pasteX + (xEnd-xStart)/7) < getWidth()) {
|
||||||
|
pasteX++;
|
||||||
|
} else {
|
||||||
|
pasteX--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.err.println("Unable to paste from source image, no matching platform data.");
|
System.out.println("Paste to "+pasteX+","+pasteY);
|
||||||
} else {
|
for (int sourceY = yStart, targetY = pasteY; sourceY <= yEnd; sourceY++, targetY++) {
|
||||||
System.err.println("Unable to paste partial images at this time... sorry. :-(");
|
if (targetY < 0 || targetY >= getHeight()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int sourceRow = sourceY * getWidth();
|
||||||
|
int targetRow = targetY * getWidth();
|
||||||
|
for (int sourceX = xStart, targetX = pasteX; sourceX <= xEnd; sourceX++, targetX++) {
|
||||||
|
if (targetX < 0 || targetX/7 >= getWidth()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int targetLoc = targetRow + targetX/7;
|
||||||
|
byte sourceByte = sourceData[sourceRow + sourceX/7];
|
||||||
|
byte targetByte = targetData[targetLoc];
|
||||||
|
int targetBit = targetX % 7;
|
||||||
|
int sourceBit = sourceX % 7;
|
||||||
|
// Remove hi-bit and image bit
|
||||||
|
targetByte &= 0x07f ^ (1 << targetBit);
|
||||||
|
// Copy hi-bit
|
||||||
|
targetByte |= sourceByte & 0x080;
|
||||||
|
// Copy x bit
|
||||||
|
targetByte |= ((sourceByte >> sourceBit) & 1) << targetBit;
|
||||||
|
targetData[targetLoc] = targetByte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setDataAndRedraw(targetData);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -456,12 +537,16 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void select() {
|
public void select() {
|
||||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
_setDrawMode(DrawMode.Select);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectNone() {
|
public void selectNone() {
|
||||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
selectStartX = selectStartY = selectEndX = selectEndY = -1;
|
||||||
|
setSelectionArea(selectStartX, selectStartY, selectEndX, selectEndY);
|
||||||
|
if (selectRect != null) {
|
||||||
|
anchorPane.getChildren().remove(selectRect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void importImage(javafx.scene.image.Image image) {
|
private void importImage(javafx.scene.image.Image image) {
|
||||||
@@ -504,7 +589,7 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
|
|||||||
public void resize(final int newWidth, final int newHeight) {
|
public void resize(final int newWidth, final int newHeight) {
|
||||||
UIAction.confirm("Do you want to scale the image? If you select no, the image will be cropped as needed.", () -> {
|
UIAction.confirm("Do you want to scale the image? If you select no, the image will be cropped as needed.", () -> {
|
||||||
rescale(newWidth, newHeight);
|
rescale(newWidth, newHeight);
|
||||||
}, () -> {
|
}, () -> {
|
||||||
crop(newWidth, newHeight);
|
crop(newWidth, newHeight);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user