Drawing API cleanup
This commit is contained in:
parent
cae3f0b2cf
commit
7cc298638c
@ -8,7 +8,7 @@ import lombok.Getter;
|
|||||||
@Getter
|
@Getter
|
||||||
public class Environment {
|
public class Environment {
|
||||||
|
|
||||||
private final Publisher<Drawing> onNewDrawing = new Publisher<>();
|
private final Publisher<Drawing> onDrawingChange = new Publisher<>();
|
||||||
|
|
||||||
private final Tools tools = new Tools();
|
private final Tools tools = new Tools();
|
||||||
|
|
||||||
@ -19,8 +19,8 @@ public class Environment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void newDrawing() {
|
public void newDrawing() {
|
||||||
drawing = new Drawing(1920, 1080);
|
drawing = new Drawing(1920, 1080, onDrawingChange::publish);
|
||||||
onNewDrawing.publish(drawing);
|
onDrawingChange.publish(drawing);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package de.ph87.kindermalen.drawing;
|
package de.ph87.kindermalen.drawing;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@ -10,6 +11,7 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ToString
|
@ToString
|
||||||
@ -19,41 +21,37 @@ public class Drawing {
|
|||||||
|
|
||||||
public final int height;
|
public final int height;
|
||||||
|
|
||||||
|
private final Consumer<Drawing> onChange;
|
||||||
|
|
||||||
public final ZonedDateTime created = ZonedDateTime.now();
|
public final ZonedDateTime created = ZonedDateTime.now();
|
||||||
|
|
||||||
|
@Getter
|
||||||
@ToString.Exclude
|
@ToString.Exclude
|
||||||
private final Layer current;
|
private final Layer layer;
|
||||||
|
|
||||||
public Drawing(final int width, final int height) {
|
public Drawing(final int width, final int height, final Consumer<Drawing> onChange) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
current = new Layer(width, height);
|
this.onChange = onChange;
|
||||||
|
layer = new Layer(width, height, l -> onChange.accept(this));
|
||||||
log.info("New Drawing: {}", this);
|
log.info("New Drawing: {}", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Graphics2D getGraphics() {
|
|
||||||
return (Graphics2D) current.getCurrent().getGraphics();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void publish() {
|
|
||||||
current.publish();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void undo() {
|
public void undo() {
|
||||||
current.undo();
|
layer.undo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void redo() {
|
public void redo() {
|
||||||
current.redo();
|
layer.redo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void newRevision() {
|
public void newRevision() {
|
||||||
current.newRevision();
|
layer.newRevision();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(final File dir) throws IOException {
|
public void save(final File dir) throws IOException {
|
||||||
final int revision = current.getRevision();
|
final int revision = layer.getRevision();
|
||||||
final BufferedImage image = current.getCurrent();
|
final BufferedImage image = layer.getBuffer();
|
||||||
final File subdir = new File(dir, created.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
|
final File subdir = new File(dir, created.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
|
||||||
final File file = new File(subdir, "%05d".formatted(revision) + ".png");
|
final File file = new File(subdir, "%05d".formatted(revision) + ".png");
|
||||||
if (subdir.mkdirs()) {
|
if (subdir.mkdirs()) {
|
||||||
@ -69,7 +67,7 @@ public class Drawing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Image getImage() {
|
public Image getImage() {
|
||||||
return current.getCurrent();
|
return layer.getBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,7 @@ public class DrawingPanel extends MyComponent {
|
|||||||
public DrawingPanel(final Environment environment) {
|
public DrawingPanel(final Environment environment) {
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
subscribe(environment.getTools().getOnSelect(), this::onToolSelect);
|
subscribe(environment.getTools().getOnSelect(), this::onToolSelect);
|
||||||
subscribe(environment.getOnNewDrawing(), drawing -> repaint());
|
subscribe(environment.getOnDrawingChange(), drawing -> repaint());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onToolSelect(final Tool tool) {
|
private void onToolSelect(final Tool tool) {
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
package de.ph87.kindermalen.drawing;
|
package de.ph87.kindermalen.drawing;
|
||||||
|
|
||||||
import de.ph87.kindermalen.util.Publisher;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static de.ph87.kindermalen.util.ImageHelper.COPY;
|
import static de.ph87.kindermalen.util.ImageHelper.COPY;
|
||||||
|
|
||||||
@ -17,25 +18,25 @@ public class Layer {
|
|||||||
|
|
||||||
private final int height;
|
private final int height;
|
||||||
|
|
||||||
@Getter
|
private final Consumer<Layer> onChange;
|
||||||
private BufferedImage current;
|
|
||||||
|
|
||||||
private List<BufferedImage> history = new ArrayList<>();
|
private List<BufferedImage> history = new ArrayList<>();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private BufferedImage buffer;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private int index = 0;
|
private int index = 0;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private int revision = 0;
|
private int revision = 0;
|
||||||
|
|
||||||
@Getter
|
public Layer(final int width, final int height, final Consumer<Layer> onChange) {
|
||||||
private final Publisher<BufferedImage> onChange = new Publisher<>();
|
|
||||||
|
|
||||||
public Layer(final int width, final int height) {
|
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.current = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
this.onChange = onChange;
|
||||||
this.history.add(current);
|
this.buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
this.history.add(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void newRevision() {
|
public void newRevision() {
|
||||||
@ -45,19 +46,19 @@ public class Layer {
|
|||||||
history = history.subList(0, keep);
|
history = history.subList(0, keep);
|
||||||
log.info("{} Revisions deleted", old - keep);
|
log.info("{} Revisions deleted", old - keep);
|
||||||
}
|
}
|
||||||
current = COPY(current);
|
buffer = COPY(buffer);
|
||||||
index = history.size();
|
index = history.size();
|
||||||
revision++;
|
revision++;
|
||||||
history.add(current);
|
history.add(buffer);
|
||||||
log.debug("Revision {} created", index);
|
log.debug("Revision {} created", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void undo() {
|
public void undo() {
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
index--;
|
index--;
|
||||||
current = history.get(index);
|
buffer = history.get(index);
|
||||||
log.info("UNDO: Revision {} loaded", index);
|
log.info("UNDO: Revision {} loaded", index);
|
||||||
publish();
|
onChange.accept(this);
|
||||||
} else {
|
} else {
|
||||||
log.warn("No UNDO steps left.");
|
log.warn("No UNDO steps left.");
|
||||||
}
|
}
|
||||||
@ -66,9 +67,9 @@ public class Layer {
|
|||||||
public void redo() {
|
public void redo() {
|
||||||
if (canRedo()) {
|
if (canRedo()) {
|
||||||
index++;
|
index++;
|
||||||
current = history.get(index);
|
buffer = history.get(index);
|
||||||
log.info("REDO: Revision {} loaded", index);
|
log.info("REDO: Revision {} loaded", index);
|
||||||
publish();
|
onChange.accept(this);
|
||||||
} else {
|
} else {
|
||||||
log.warn("No REDO steps left.");
|
log.warn("No REDO steps left.");
|
||||||
}
|
}
|
||||||
@ -78,8 +79,10 @@ public class Layer {
|
|||||||
return index < history.size() - 1;
|
return index < history.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void publish() {
|
public void draw(final BufferedImage image, final int x, final int y) {
|
||||||
onChange.publish(current);
|
final Graphics2D g = (Graphics2D) buffer.getGraphics();
|
||||||
|
g.drawImage(image, x, y, null);
|
||||||
|
onChange.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -96,8 +96,9 @@ public class StampTool extends Tool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void apply(final Drawing drawing, final Vector point) {
|
private void apply(final Drawing drawing, final Vector point) {
|
||||||
drawing.getGraphics().drawImage(prepared, point.intX() - prepared.getWidth() / 2, point.intY() - prepared.getHeight() / 2, null);
|
final int x = point.intX() - prepared.getWidth() / 2;
|
||||||
drawing.publish();
|
final int y = point.intY() - prepared.getHeight() / 2;
|
||||||
|
drawing.getLayer().draw(prepared, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user