Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.RectangularShape;
import java.awt.geom.*;
import java.io.Serial;
import java.util.*;
import java.util.List;
Expand All @@ -43,6 +41,7 @@
import net.rptools.maptool.client.ui.zone.renderer.ZoneRenderer;
import net.rptools.maptool.client.walker.WalkerMetric;
import net.rptools.maptool.events.MapToolEventBus;
import net.rptools.maptool.language.I18N;
import net.rptools.maptool.model.*;
import net.rptools.maptool.model.drawing.*;
import org.apache.logging.log4j.LogManager;
Expand Down Expand Up @@ -240,7 +239,7 @@ protected void detachFrom(ZoneRenderer renderer) {
}

/**
* Set <kbd>DELETE</kbd> to delete selected drawn elements. Set <kbd>CTRL</kbd>+<kbd>V</kbd> to
* Set <kbd>DELETE</kbd> to delete selected drawn elements. Set <kbd>CTRL</kbd>+<kbd>D</kbd> to
* duplicate selected drawn elements.
*
* @param actionMap What keys do what action.
Expand All @@ -250,7 +249,7 @@ protected void installKeystrokes(Map<KeyStroke, Action> actionMap) {
super.installKeystrokes(actionMap);
actionMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), deleteAction);
actionMap.put(
KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK), duplicateAction);
KeyStroke.getKeyStroke(KeyEvent.VK_D, InputEvent.CTRL_DOWN_MASK), duplicateAction);
}

/**
Expand Down Expand Up @@ -436,7 +435,7 @@ public void mouseReleased(MouseEvent e) {
}
}

if (SwingUtilities.isRightMouseButton(e)) {
if (SwingUtilities.isRightMouseButton(e) && isDraggingMap()) {
cancelMapDrag(); // We no longer drag the map. Fixes bug #616
return;
}
Expand Down Expand Up @@ -1085,9 +1084,9 @@ private void paintTemplateCursor(
}

/**
* Paint the dragged movement distance in feet according to the Movement Metric setting.
* Paint the dragged movement distance according to the Movement Metric setting.
*
* <p>Label is displayed below the template (i.e. similar to dragging a token)
* <p>Label is displayed near the dragged terminus
*
* @param g where to draw.
* @param startVertex the starting point.
Expand All @@ -1112,10 +1111,9 @@ private void paintTemplateMovementLabel(

if (moveDistance != 0) {
Rectangle bounds = at.getBounds(zone);
int x = (int) (bounds.getMinX() + bounds.getMaxX()) / 2;
int y = (int) (bounds.getMaxY());
ScreenPoint centerText = renderer.getViewModel().getZoneScale().toScreenSpace(x, y);

ScreenPoint centerText =
renderer.getViewModel().getZoneScale().toScreenSpace(endVertex.x, endVertex.y);
centerText.translate(CURSOR_WIDTH, CURSOR_WIDTH);
ToolHelper.drawMeasurement(g, moveDistance, (int) centerText.x, (int) centerText.y);
}
}
Expand Down Expand Up @@ -1176,19 +1174,23 @@ private void paintTemplateMovementLine(
}

/**
* Paint the radius value in feet. To be displayed above the template vertex (i.e. same as when
* drawing a template)
* Paint the template radius value label.
*
* <p>Label is displayed to the right of the template.
*
* @param g where to paint.
* @param zp where on the map to paint the radius label.
*/
private void paintTemplateRadiusLabel(Graphics2D g, ZonePoint zp, AbstractTemplate at) {
if (at.getRadius() > 0) {
ScreenPoint centerText = renderer.getViewModel().getZoneScale().toScreenSpace(zp.x, zp.y);
centerText.translate(CURSOR_WIDTH, -CURSOR_WIDTH);
Zone zone = getZone();
Rectangle bounds = at.getBounds(zone);
int x = (int) bounds.getMaxX();
int y = (int) (bounds.getMinY() + bounds.getMaxY()) / 2;
ScreenPoint centerText = renderer.getViewModel().getZoneScale().toScreenSpace(x, y);
ToolHelper.drawMeasurement(
g, at.getRadius() * getZone().getUnitsPerCell(), (int) centerText.x, (int) centerText.y);
} // endif
}
}

/**
Expand Down Expand Up @@ -1359,14 +1361,55 @@ private void updateDraggedDrawnElements(MouseEvent e, ShapeDrawable sd) {
dragPointOffset.y = dragWorkingZonePoint.y - dragPointOffset.y;
}

if (sd.getShape() instanceof RectangularShape rs) {
Shape s = sd.getShape();
if (s instanceof RectangularShape rs) {
rs.setFrame(
rs.getBounds().x - dragPointOffset.x,
rs.getBounds().y - dragPointOffset.y,
rs.getX() - dragPointOffset.x,
rs.getY() - dragPointOffset.y,
rs.getWidth(),
rs.getHeight());
} else if (sd.getShape() instanceof Polygon p) {
} else if (s instanceof Polygon p) {
p.translate(-dragPointOffset.x, -dragPointOffset.y);
} else if (s instanceof Area a) {
AffineTransform tx =
AffineTransform.getTranslateInstance(-dragPointOffset.x, -dragPointOffset.y);
a.transform(tx);
} else if (s instanceof Path2D p2d) {
AffineTransform tx =
AffineTransform.getTranslateInstance(-dragPointOffset.x, -dragPointOffset.y);
p2d.transform(tx);
} else if (s instanceof Line2D line) {
line.setLine(
line.getX1() - dragPointOffset.x,
line.getY1() - dragPointOffset.y,
line.getX2() - dragPointOffset.x,
line.getY2() - dragPointOffset.y);
} else if (s instanceof QuadCurve2D quad) {
quad.setCurve(
quad.getX1() - dragPointOffset.x,
quad.getY1() - dragPointOffset.y,
quad.getCtrlX() - dragPointOffset.x,
quad.getCtrlY() - dragPointOffset.y,
quad.getX2() - dragPointOffset.x,
quad.getY2() - dragPointOffset.y);
} else if (s instanceof CubicCurve2D cubic) {
cubic.setCurve(
cubic.getX1() - dragPointOffset.x,
cubic.getY1() - dragPointOffset.y,
cubic.getCtrlX1() - dragPointOffset.x,
cubic.getCtrlY1() - dragPointOffset.y,
cubic.getCtrlX2() - dragPointOffset.x,
cubic.getCtrlY2() - dragPointOffset.y,
cubic.getX2() - dragPointOffset.x,
cubic.getY2() - dragPointOffset.y);
} else {
// log that we cannot drag certain types of shape that are being dragged
log.warn(
I18N.getText(
"tool.drawingpointer.draggingUnsupportedShapeType",
s.getClass().getSimpleName(),
sd.getId(),
sd.getName()));
}
}

Expand Down
29 changes: 19 additions & 10 deletions src/main/java/net/rptools/maptool/model/drawing/LineSegment.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ public class LineSegment extends AbstractDrawing {
private final List<Point> points = new ArrayList<Point>();
private @Nonnull Float width;
private boolean squareCap;
private transient int lastPointCount = -1;
private transient Rectangle cachedBounds;
private transient Area area;

Expand Down Expand Up @@ -109,8 +108,8 @@ private Object readResolve() {
* @param y
*/
public void addPoint(int x, int y) {
area = null;
points.add(new Point(x, y));
invalidateGeometryCache();
}

/**
Expand All @@ -137,10 +136,10 @@ public List<Point> getPoints() {
* @param deltaY offset in the Y axis
*/
public void translate(int deltaX, int deltaY) {
points.replaceAll(point1 -> new Point(point1.x + deltaX, point1.y + deltaY));
if (cachedBounds != null) {
cachedBounds.translate(deltaX, deltaY);
for (Point p : points) {
p.translate(deltaX, deltaY);
}
invalidateGeometryCache();
}

@Override
Expand Down Expand Up @@ -179,7 +178,7 @@ public static LineSegment fromDto(LineSegmentDrawableDto dto) {
}

private Area createLineArea() {
if (points.size() < 1) {
if (points.isEmpty()) {
return null;
}
GeneralPath gp = null;
Expand Down Expand Up @@ -210,11 +209,13 @@ protected void drawBackground(Zone zone, Graphics2D g) {

@Override
public Rectangle getBounds(Zone zone) {
if (lastPointCount == points.size()) {
if (cachedBounds != null) {
return cachedBounds;
}
if (points.size() < 1) return null;
Rectangle bounds = new Rectangle(points.get(0));
if (points.isEmpty()) {
return null;
}
Rectangle bounds = new Rectangle(points.getFirst());
for (Point point : points) {
bounds.add(point);
}
Expand All @@ -227,7 +228,6 @@ public Rectangle getBounds(Zone zone) {
bounds.height = 1;
}
cachedBounds = bounds;
lastPointCount = points.size();
return bounds;
}

Expand All @@ -248,4 +248,13 @@ public int getStrokeJoin() {
if (squareCap) return BasicStroke.JOIN_MITER;
else return BasicStroke.JOIN_ROUND;
}

/**
* Line segment geometry can mutate with either the number of points or point co-ordinate change.
* Whenever one of these change the bounds and area caches should be invalidated.
*/
private void invalidateGeometryCache() {
cachedBounds = null;
area = null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2954,6 +2954,7 @@ tool.deletedrawing.instructions = LClick: Select drawings Double-Click: Delete
tool.deletedrawing.tooltip = Delete drawing tool
tool.drawingpointer.tooltip = Drawing pointer tool.
tool.drawingpointer.instructions = Hover: show label. RClick: Popupmenu. LClick: Select drawings. LClick+Shift: multiselect. LClick+Ctrl: select stack next. LDrag: Selection box. LDrag+Shift: multiselect. LDrag+Ctrl: Selection box match stroke color. LDrag+Alt: Selection box match fill color. Selected+DELETE: delete.
tool.drawingpointer.draggingUnsupportedShapeType = Dragging {0} shape types is not supported. Shape id: {1} Shape name: {2}
tool.templatepointer.tooltip = Template pointer tool.
tool.templatepointer.instructions= Hover: show label. RClick: Popupmenu. LClick: Select templates. LClick+Shift: multiselect. LClick+Ctrl: select stack next. LDrag: Selection box. LDrag+Shift: multiselect. LDrag+Ctrl: Selection box match stroke color. LDrag+Alt: Selection box match fill color. LDrag selected template: Move. LDrag+Ctrl+single template: change radius/size. LDrag+Alt+single template: change path vertex. Selected+DELETE: delete. Selected+CTRL+V: duplicate.
tool.isorectangle.tooltip = Draw an isometric rectangle.
Expand Down
Loading