Skip to content

Commit 5d6504a

Browse files
Merge pull request #5581 from bubblobill/grid-renderer
Grid Renderer - Improved appearance of grids
2 parents 38e2e60 + 85d4f69 commit 5d6504a

File tree

9 files changed

+138
-65
lines changed

9 files changed

+138
-65
lines changed

src/main/java/net/rptools/maptool/client/AppActions.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2741,12 +2741,12 @@ public GridSizeAction(int size) {
27412741

27422742
@Override
27432743
public boolean isSelected() {
2744-
return AppState.getGridSize() == size;
2744+
return AppState.getGridLineWeight() == size;
27452745
}
27462746

27472747
@Override
27482748
protected void executeAction() {
2749-
AppState.setGridSize(size);
2749+
AppState.setGridLineWeight(size);
27502750
MapTool.getFrame().refresh();
27512751
}
27522752
}

src/main/java/net/rptools/maptool/client/AppState.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public class AppState {
3535
private static boolean showTextLabels = true;
3636
private static boolean enforceNotification = false;
3737
private static File campaignFile;
38-
private static int gridSize = 1;
38+
private static int gridLineWeight = 1;
3939
private static boolean showLumensOverlay;
4040
private static boolean showLights;
4141
private static boolean showAsPlayer = false;
@@ -79,12 +79,12 @@ public static void setLoggingToConsole(boolean flag) {
7979
isLoggingToConsole = flag;
8080
}
8181

82-
public static int getGridSize() {
83-
return gridSize;
82+
public static int getGridLineWeight() {
83+
return gridLineWeight;
8484
}
8585

86-
public static void setGridSize(int size) {
87-
gridSize = size;
86+
public static void setGridLineWeight(int size) {
87+
gridLineWeight = size;
8888
}
8989

9090
public static boolean useDoubleWideLine() {

src/main/java/net/rptools/maptool/client/ui/zone/gdx/GridRenderer.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import com.badlogic.gdx.graphics.g2d.Batch;
2020
import com.badlogic.gdx.math.Matrix4;
2121
import com.badlogic.gdx.utils.Pools;
22-
import java.awt.*;
2322
import net.rptools.maptool.client.AppState;
2423
import net.rptools.maptool.client.ui.zone.renderer.ZoneRendererConstants;
2524
import net.rptools.maptool.model.*;
@@ -80,14 +79,13 @@ private void renderGrid(HexGrid grid) {
8079
tmpColor.premultiplyAlpha();
8180
drawer.setColor(tmpColor);
8281
var floats = areaRenderer.pathToFloatArray(scaledHex.getPathIterator(null));
83-
var lineWidth = AppState.getGridSize();
82+
var lineWidth = AppState.getGridLineWeight();
8483

8584
for (double v = offV % (scaledMinorRadius * 2) - (scaledMinorRadius * 2);
8685
v < grid.getRendererSizeV(renderer);
8786
v += scaledMinorRadius) {
8887
double offsetU = (int) ((count & 1) == 0 ? 0 : -(scaledEdgeProjection + scaledEdgeLength));
8988
count++;
90-
9189
double start =
9290
offU % (2 * scaledEdgeLength + 2 * scaledEdgeProjection)
9391
- (2 * scaledEdgeLength + 2 * scaledEdgeProjection);
@@ -166,7 +164,7 @@ private void drawHatch(IsometricGrid grid, float x, float y) {
166164
double isoWidth = grid.getSize() * zoneCache.getZoneRenderer().getScale();
167165
int hatchSize = isoWidth > 10 ? (int) isoWidth / 8 : 2;
168166

169-
var lineWidth = AppState.getGridSize();
167+
var lineWidth = AppState.getGridLineWeight();
170168

171169
drawer.line(x - (hatchSize * 2), y - hatchSize, x + (hatchSize * 2), y + hatchSize, lineWidth);
172170
drawer.line(x - (hatchSize * 2), y + hatchSize, x + (hatchSize * 2), y - hatchSize, lineWidth);
@@ -196,7 +194,7 @@ private void renderGrid(SquareGrid grid) {
196194
var startCol = ((int) (x / gridSize) * gridSize);
197195
var startRow = ((int) (y / gridSize) * gridSize);
198196

199-
var lineWidth = AppState.getGridSize();
197+
var lineWidth = AppState.getGridLineWeight();
200198

201199
for (float row = startRow; row < y + h + gridSize; row += gridSize) {
202200
var rounded = Math.round(h - (row + offY));

src/main/java/net/rptools/maptool/client/ui/zone/renderer/GridRenderer.java

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,100 @@
1414
*/
1515
package net.rptools.maptool.client.ui.zone.renderer;
1616

17+
import com.github.weisj.jsvg.util.ColorUtil;
18+
import com.google.common.eventbus.Subscribe;
1719
import java.awt.*;
20+
import net.rptools.lib.image.ImageUtil;
1821
import net.rptools.maptool.client.AppState;
1922
import net.rptools.maptool.client.ui.zone.PlayerView;
20-
import net.rptools.maptool.model.Zone;
23+
import net.rptools.maptool.events.MapToolEventBus;
24+
import net.rptools.maptool.model.*;
25+
import net.rptools.maptool.model.zones.GridChanged;
2126

2227
public class GridRenderer {
23-
private final Zone zone;
2428
private final ZoneRenderer renderer;
29+
private Zone zone;
30+
private static float gridLineWeight;
31+
private static float scale;
32+
private static float baseWidth = 2f;
33+
private static Color[] gridColours;
34+
private int baseColourInt = -1;
2535

26-
public GridRenderer(ZoneRenderer renderer) {
36+
GridRenderer(ZoneRenderer renderer) {
37+
new MapToolEventBus().getMainEventBus().register(this);
2738
this.renderer = renderer;
2839
this.zone = renderer.getZone();
40+
setGridColours();
41+
}
42+
43+
@SuppressWarnings("unused")
44+
@Subscribe
45+
private void onGridChanged(GridChanged event) {
46+
if (event.zone() != null) {
47+
this.zone = event.zone();
48+
setGridColours();
49+
}
50+
}
51+
52+
private void setGridColours() {
53+
int gridColourInt = zone.getGridColor();
54+
if (this.baseColourInt == gridColourInt) {
55+
return;
56+
}
57+
this.baseColourInt = gridColourInt;
58+
Color gc = new Color(baseColourInt);
59+
Color contrast = new Color(ImageUtil.negativeColourInt(baseColourInt));
60+
gridColours =
61+
new Color[] {
62+
gc,
63+
ColorUtil.withAlpha(gc, 0.14f),
64+
ColorUtil.withAlpha(contrast, 0.04f),
65+
ColorUtil.withAlpha(contrast, 0.05f)
66+
};
67+
}
68+
69+
public static void drawGridShape(Graphics2D g, Shape shape) {
70+
if (scale > 0.49f) {
71+
for (int i = 3; i > -1; i--) {
72+
g.setColor(gridColours[i]);
73+
g.setStroke(
74+
new BasicStroke(
75+
baseWidth * (i + 1) * 0.5f * gridLineWeight * scale,
76+
BasicStroke.CAP_ROUND,
77+
BasicStroke.JOIN_MITER));
78+
g.draw(shape);
79+
}
80+
} else {
81+
g.setColor(gridColours[0]);
82+
g.setStroke(
83+
new BasicStroke(
84+
Math.clamp(
85+
baseWidth * gridLineWeight * scale,
86+
baseWidth * gridLineWeight * 0.15f,
87+
baseWidth * gridLineWeight * 0.25f),
88+
BasicStroke.CAP_ROUND,
89+
BasicStroke.JOIN_MITER));
90+
g.draw(shape);
91+
}
2992
}
3093

3194
public void renderGrid(Graphics2D g, PlayerView view) {
32-
int gridSize = (int) (zone.getGrid().getSize() * renderer.getScale());
33-
if (!AppState.isShowGrid() || gridSize < ZoneRendererConstants.MIN_GRID_SIZE) {
95+
if (!AppState.isShowGrid()
96+
|| zone.getGrid().getSize() * renderer.getScale() < ZoneRendererConstants.MIN_GRID_SIZE) {
3497
return;
3598
}
99+
gridLineWeight = AppState.getGridLineWeight();
100+
scale = (float) renderer.getScale();
101+
baseWidth = zone.getGrid().getSize() / 50f;
102+
if (gridColours == null) {
103+
setGridColours();
104+
}
36105
zone.getGrid().draw(renderer, g, g.getClipBounds());
37106
}
38107

39108
public void renderCoordinates(Graphics2D g, PlayerView view) {
40109
if (AppState.isShowCoordinates()) {
41-
zone.getGrid().drawCoordinatesOverlay(g, renderer);
110+
zone.getGrid().drawCoordinatesOverlay(g, this.renderer);
42111
}
43112
}
44113
}

src/main/java/net/rptools/maptool/client/ui/zone/renderer/HaloRenderer.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import java.util.HashMap;
2222
import java.util.Map;
2323
import net.rptools.maptool.client.AppPreferences;
24-
import net.rptools.maptool.client.AppState;
2524
import net.rptools.maptool.client.ui.zone.ZoneViewModel;
2625
import net.rptools.maptool.model.*;
2726
import org.apache.logging.log4j.LogManager;
@@ -35,7 +34,6 @@ public class HaloRenderer {
3534
private Grid grid;
3635
private Shape haloShape;
3736
private Shape paintShape;
38-
private final int gridLineWeight = AppState.getGridSize();
3937

4038
public HaloRenderer(RenderHelper renderHelper) {
4139
this.renderHelper = renderHelper;

src/main/java/net/rptools/maptool/model/HexGrid.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import net.rptools.maptool.client.swing.SwingUtil;
3232
import net.rptools.maptool.client.ui.theme.Images;
3333
import net.rptools.maptool.client.ui.theme.RessourceManager;
34+
import net.rptools.maptool.client.ui.zone.renderer.GridRenderer;
3435
import net.rptools.maptool.client.ui.zone.renderer.ZoneRenderer;
3536
import net.rptools.maptool.server.proto.GridDto;
3637
import net.rptools.maptool.server.proto.HexGridDto;
@@ -359,7 +360,7 @@ public void draw(ZoneRenderer renderer, Graphics2D g, Rectangle bounds) {
359360

360361
Object oldAntiAlias = SwingUtil.useAntiAliasing(g);
361362
g.setColor(new Color(getZone().getGridColor()));
362-
g.setStroke(new BasicStroke(AppState.getGridSize()));
363+
g.setStroke(new BasicStroke(AppState.getGridLineWeight()));
363364

364365
for (double v = offV % (scaledMinorRadius * 2) - (scaledMinorRadius * 2);
365366
v < getRendererSizeV(renderer);
@@ -374,7 +375,7 @@ public void draw(ZoneRenderer renderer, Graphics2D g, Rectangle bounds) {
374375
double incr = 2 * scaledEdgeLength + 2 * scaledEdgeProjection;
375376
for (double u = start; u < end; u += incr) {
376377
setGridDrawTranslation(g, u + offsetU, v);
377-
g.draw(scaledHex);
378+
GridRenderer.drawGridShape(g, scaledHex);
378379
setGridDrawTranslation(g, -(u + offsetU), -v);
379380
}
380381
}

src/main/java/net/rptools/maptool/model/IsometricGrid.java

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@
2525
import javax.swing.Action;
2626
import javax.swing.KeyStroke;
2727
import net.rptools.maptool.client.AppPreferences;
28-
import net.rptools.maptool.client.AppState;
2928
import net.rptools.maptool.client.MapTool;
3029
import net.rptools.maptool.client.tool.PointerTool;
3130
import net.rptools.maptool.client.ui.theme.Images;
3231
import net.rptools.maptool.client.ui.theme.RessourceManager;
32+
import net.rptools.maptool.client.ui.zone.renderer.GridRenderer;
3333
import net.rptools.maptool.client.ui.zone.renderer.ZoneRenderer;
3434
import net.rptools.maptool.client.walker.WalkerMetric;
3535
import net.rptools.maptool.client.walker.ZoneWalker;
@@ -76,7 +76,7 @@ public double getCellWidthHalf() {
7676
}
7777

7878
public double getCellHeightHalf() {
79-
return getSize() / 2;
79+
return getSize() / 2f;
8080
}
8181

8282
@Override
@@ -283,7 +283,7 @@ protected int getTokenFacingAngleRelativeToGridAxis(Token token) {
283283
Area cellShape = createCellShape(footprint.height);
284284
// convert the area to isometric view
285285
AffineTransform mtx = new AffineTransform();
286-
mtx.translate(-footprint.width / 2, -footprint.height / 2);
286+
mtx.translate(-footprint.width / 2f, -footprint.height / 2f);
287287
cellShape.transform(mtx);
288288
return cellShape;
289289
}
@@ -319,8 +319,7 @@ public void draw(ZoneRenderer renderer, Graphics2D g, Rectangle bounds) {
319319
double gridSize = getSize() * scale;
320320
double isoHeight = getSize() * scale;
321321
double isoWidth = getSize() * 2 * scale;
322-
323-
g.setColor(new Color(getZone().getGridColor()));
322+
Path2D path = new Path2D.Double();
324323

325324
int offX = (int) (renderer.getViewOffsetX() % isoWidth + getOffsetX() * scale);
326325
int offY = (int) (renderer.getViewOffsetY() % gridSize + getOffsetY() * scale);
@@ -330,7 +329,7 @@ public void draw(ZoneRenderer renderer, Graphics2D g, Rectangle bounds) {
330329

331330
for (double row = startRow; row < bounds.y + bounds.height + gridSize; row += gridSize) {
332331
for (double col = startCol; col < bounds.x + bounds.width + isoWidth; col += isoWidth) {
333-
drawHatch(renderer, g, (int) (col + offX), (int) (row + offY));
332+
path.append(drawHatch(renderer, (int) (col + offX), (int) (row + offY)), false);
334333
}
335334
}
336335

@@ -340,17 +339,23 @@ public void draw(ZoneRenderer renderer, Graphics2D g, Rectangle bounds) {
340339
for (double col = startCol - (isoWidth / 2);
341340
col < bounds.x + bounds.width + isoWidth;
342341
col += isoWidth) {
343-
drawHatch(renderer, g, (int) (col + offX), (int) (row + offY));
342+
path.append(drawHatch(renderer, (int) (col + offX), (int) (row + offY)), false);
344343
}
345344
}
345+
GridRenderer.drawGridShape(g, path);
346346
}
347347

348-
private void drawHatch(ZoneRenderer renderer, Graphics2D g, int x, int y) {
348+
private Shape drawHatch(ZoneRenderer renderer, int x, int y) {
349349
double isoWidth = getSize() * renderer.getScale();
350350
int hatchSize = isoWidth > 10 ? (int) isoWidth / 8 : 2;
351-
g.setStroke(new BasicStroke(AppState.getGridSize()));
352-
g.drawLine(x - (hatchSize * 2), y - hatchSize, x + (hatchSize * 2), y + hatchSize);
353-
g.drawLine(x - (hatchSize * 2), y + hatchSize, x + (hatchSize * 2), y - hatchSize);
351+
Path2D path = new Path2D.Double();
352+
path.append(
353+
new Line2D.Double(x - (hatchSize * 2), y - hatchSize, x + (hatchSize * 2), y + hatchSize),
354+
false);
355+
path.append(
356+
new Line2D.Double(x - (hatchSize * 2), y + hatchSize, x + (hatchSize * 2), y - hatchSize),
357+
false);
358+
return path;
354359
}
355360

356361
/**
@@ -377,7 +382,7 @@ private static BufferedImage rotate(BufferedImage planImage) {
377382
BufferedImage rotateImage = new BufferedImage(neww, newh, BufferedImage.TYPE_INT_ARGB);
378383
Graphics2D g = rotateImage.createGraphics();
379384
g.translate((neww - w) / 2, (newh - h) / 2);
380-
g.rotate(Math.toRadians(45), w / 2, h / 2);
385+
g.rotate(Math.toRadians(45), w / 2f, h / 2f);
381386
g.drawRenderedImage(planImage, null);
382387
g.dispose();
383388
// scale image to half height
@@ -414,22 +419,22 @@ private static Area rotate(Area planArea) {
414419
int neww = (int) Math.floor(w * cos + h * sin);
415420
int newh = (int) Math.floor(h * cos + w * sin);
416421

417-
double scaleX = neww / w;
418-
double scaleY = newh / h;
422+
double scaleX = 1f * neww / w;
423+
double scaleY = 1f * newh / h;
419424

420425
int tx = (neww - w) / 2;
421426
int ty = (newh - h) / 2;
422427

423428
// Rotate Area 45 degrees
424429
AffineTransform atArea = AffineTransform.getScaleInstance(scaleX, scaleY);
425430
atArea.concatenate(AffineTransform.getTranslateInstance(tx, ty));
426-
atArea.concatenate(AffineTransform.getRotateInstance(Math.toRadians(45), w / 2, h / 2));
431+
atArea.concatenate(AffineTransform.getRotateInstance(Math.toRadians(45), w / 2f, h / 2f));
427432

428433
return new Area(atArea.createTransformedShape(planArea));
429434
}
430435

431436
private static Area resize(Area planArea, int newWidth, int newHeight) {
432-
// Resize into a Area
437+
// Resize into an Area
433438
double w = planArea.getBounds().width, h = planArea.getBounds().height;
434439
double scaleX = newWidth / w;
435440
double scaleY = newHeight / h;

0 commit comments

Comments
 (0)