From cd8c57c6b045990a042e54e7d8e55ba2f486df9a Mon Sep 17 00:00:00 2001
From: Baaaaaz <131240480+Baaaaaz@users.noreply.github.com>
Date: Wed, 15 Jul 2026 06:34:42 +0100
Subject: [PATCH 1/6] change movement and size label positions
---
.../tool/drawing/DrawingPointerTool.java | 25 +++++++++++--------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java b/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java
index 606917e4e3..f41d08bb80 100644
--- a/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java
+++ b/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java
@@ -1085,9 +1085,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.
*
- *
Label is displayed below the template (i.e. similar to dragging a token)
+ *
Label is displayed near the dragged terminus
*
* @param g where to draw.
* @param startVertex the starting point.
@@ -1112,10 +1112,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);
}
}
@@ -1176,19 +1175,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.
+ *
+ *
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
+ }
}
/**
From 873c8c6000115dc98d59077c883473ddeb561bcc Mon Sep 17 00:00:00 2001
From: Baaaaaz <131240480+Baaaaaz@users.noreply.github.com>
Date: Wed, 15 Jul 2026 06:38:41 +0100
Subject: [PATCH 2/6] fix selection border not appearing when right clicking on
an drawable that was previously unselected
---
.../rptools/maptool/client/tool/drawing/DrawingPointerTool.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java b/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java
index f41d08bb80..980f0469a6 100644
--- a/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java
+++ b/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java
@@ -436,7 +436,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;
}
From c1f6109a881ddc2896875a17bf59d8f08f335a7e Mon Sep 17 00:00:00 2001
From: Baaaaaz <131240480+Baaaaaz@users.noreply.github.com>
Date: Wed, 15 Jul 2026 07:00:38 +0100
Subject: [PATCH 3/6] change duplicate action to Ctrl+D
---
.../maptool/client/tool/drawing/DrawingPointerTool.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java b/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java
index 980f0469a6..6f7f7a4d23 100644
--- a/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java
+++ b/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java
@@ -240,7 +240,7 @@ protected void detachFrom(ZoneRenderer renderer) {
}
/**
- * Set DELETE to delete selected drawn elements. Set CTRL+V to
+ * Set DELETE to delete selected drawn elements. Set CTRL+D to
* duplicate selected drawn elements.
*
* @param actionMap What keys do what action.
@@ -250,7 +250,7 @@ protected void installKeystrokes(Map 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);
}
/**
From 4fba42a1ffd3e1062a3a8bfa988b86753158e79c Mon Sep 17 00:00:00 2001
From: Baaaaaz <131240480+Baaaaaz@users.noreply.github.com>
Date: Wed, 15 Jul 2026 17:49:42 +0100
Subject: [PATCH 4/6] fix being unable to drag certain types of shape (e.g.
drawings that had been merged)
---
.../tool/drawing/DrawingPointerTool.java | 45 ++++++++++++++++---
1 file changed, 38 insertions(+), 7 deletions(-)
diff --git a/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java b/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java
index 6f7f7a4d23..4330180704 100644
--- a/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java
+++ b/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java
@@ -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;
@@ -1362,14 +1360,47 @@ 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);
}
}
From f87a4c16701024f39267d09cb21c71209819ea99 Mon Sep 17 00:00:00 2001
From: Baaaaaz <131240480+Baaaaaz@users.noreply.github.com>
Date: Wed, 15 Jul 2026 17:52:25 +0100
Subject: [PATCH 5/6] log that we cannot drag certain types of shape that are
being dragged
---
.../maptool/client/tool/drawing/DrawingPointerTool.java | 9 +++++++++
.../net/rptools/maptool/language/i18n.properties | 1 +
2 files changed, 10 insertions(+)
diff --git a/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java b/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java
index 4330180704..ac576f5965 100644
--- a/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java
+++ b/src/main/java/net/rptools/maptool/client/tool/drawing/DrawingPointerTool.java
@@ -41,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;
@@ -1401,6 +1402,14 @@ private void updateDraggedDrawnElements(MouseEvent e, ShapeDrawable sd) {
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()));
}
}
diff --git a/src/main/resources/net/rptools/maptool/language/i18n.properties b/src/main/resources/net/rptools/maptool/language/i18n.properties
index cbd24579f0..df6c7b5919 100644
--- a/src/main/resources/net/rptools/maptool/language/i18n.properties
+++ b/src/main/resources/net/rptools/maptool/language/i18n.properties
@@ -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.
From e9503935605787cd536e2add23125433b9ad99de Mon Sep 17 00:00:00 2001
From: Baaaaaz <131240480+Baaaaaz@users.noreply.github.com>
Date: Wed, 15 Jul 2026 17:57:55 +0100
Subject: [PATCH 6/6] fix for not displaying line segments being dragged by
invalidating area and bounds caches when adding points or translating point
co-ordinates.
---
.../maptool/model/drawing/LineSegment.java | 29 ++++++++++++-------
1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/src/main/java/net/rptools/maptool/model/drawing/LineSegment.java b/src/main/java/net/rptools/maptool/model/drawing/LineSegment.java
index 18e615e63d..77092cca40 100644
--- a/src/main/java/net/rptools/maptool/model/drawing/LineSegment.java
+++ b/src/main/java/net/rptools/maptool/model/drawing/LineSegment.java
@@ -41,7 +41,6 @@ public class LineSegment extends AbstractDrawing {
private final List points = new ArrayList();
private @Nonnull Float width;
private boolean squareCap;
- private transient int lastPointCount = -1;
private transient Rectangle cachedBounds;
private transient Area area;
@@ -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();
}
/**
@@ -137,10 +136,10 @@ public List 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
@@ -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;
@@ -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);
}
@@ -227,7 +228,6 @@ public Rectangle getBounds(Zone zone) {
bounds.height = 1;
}
cachedBounds = bounds;
- lastPointCount = points.size();
return bounds;
}
@@ -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;
+ }
}