Skip to content

Commit 4b4b2cf

Browse files
authored
Merge pull request #4662 from cwisniew/better-labels-dev-merge
Update Map and Token Labels to allow users to define how they look
2 parents 1b1067d + 228eadb commit 4b4b2cf

File tree

15 files changed

+2561
-174
lines changed

15 files changed

+2561
-174
lines changed

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

Lines changed: 470 additions & 7 deletions
Large diffs are not rendered by default.
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
/*
2+
* This software Copyright by the RPTools.net development team, and
3+
* licensed under the Affero GPL Version 3 or, at your option, any later
4+
* version.
5+
*
6+
* MapTool Source Code is distributed in the hope that it will be
7+
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
8+
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9+
*
10+
* You should have received a copy of the GNU Affero General Public
11+
* License * along with this source Code. If not, please visit
12+
* <http://www.gnu.org/licenses/> and specifically the Affero license
13+
* text at <http://www.gnu.org/licenses/agpl.html>.
14+
*/
15+
package net.rptools.maptool.client.swing.label;
16+
17+
import java.awt.BasicStroke;
18+
import java.awt.Color;
19+
import java.awt.Dimension;
20+
import java.awt.Font;
21+
import java.awt.Graphics2D;
22+
import java.awt.Rectangle;
23+
import java.awt.geom.RoundRectangle2D;
24+
import javax.swing.SwingUtilities;
25+
26+
/**
27+
* The FlatImageLabel class represents an image label with customizable properties such as padding,
28+
* colors, font, and justification. It can be used to create labels for images in various
29+
* containers.
30+
*/
31+
public class FlatImageLabel {
32+
33+
/**
34+
* The Justification enum represents the different types of text justification. It can be used to
35+
* align text to the left, right, or center of a container.
36+
*/
37+
public enum Justification {
38+
/** The text is aligned to the left of the container. */
39+
Left,
40+
/** The text is aligned to the right of the container. */
41+
Right,
42+
/** The text is aligned to the center of the container. */
43+
Center
44+
}
45+
46+
/**
47+
* The padX variable represents the amount of padding to be added horizontally to the text in a
48+
* FlatImageLabel object.
49+
*
50+
* <p>This value is used in the getDimensions() and render() methods of the FlatImageLabel class
51+
* to calculate the width and positioning of the rendered text.
52+
*
53+
* <p>The padding is added on both sides of the text, resulting in a wider width of the label. It
54+
* ensures that the text is not rendered too close to the edges of the label, providing better
55+
* visual aesthetics.
56+
*
57+
* <p>The padX value should be a non-negative integer, representing the number of pixels of
58+
* padding. A higher value will result in greater horizontal spacing between the text and the
59+
* edges of the label.
60+
*
61+
* @see FlatImageLabel#getDimensions(Graphics2D, String)
62+
* @see FlatImageLabel#render(Graphics2D, int, int, String)
63+
*/
64+
private final int padX;
65+
66+
/**
67+
* The private final integer padY represents the vertical padding value for a FlatImageLabel. It
68+
* specifies the amount of empty space (in pixels) to be added above and below the text or image
69+
* within the label.
70+
*
71+
* <p>This value is set during the initialization of a FlatImageLabel object, using the padY
72+
* parameter of the constructor. Once set, the padY value cannot be changed.
73+
*
74+
* <p>The padY value should be a non-negative integer, representing the number of pixels of
75+
* padding. A higher value will result in greater vertical spacing between the text and the edges
76+
* of the label.
77+
*
78+
* @see FlatImageLabel#getDimensions(Graphics2D, String)
79+
* @see FlatImageLabel#render(Graphics2D, int, int, String)
80+
*/
81+
private final int padY;
82+
83+
/** The background variable represents the color used as the background of a FlatImageLabel. */
84+
private final Color background;
85+
86+
/**
87+
* The foreground variable holds the color value for the foreground of a FlatImageLabel object.
88+
*/
89+
private final Color foreground;
90+
91+
/**
92+
* The private final variable 'font' represents the font used for rendering text in the
93+
* FlatImageLabel class.
94+
*/
95+
private final Font font;
96+
97+
/**
98+
* The Justification enum represents the different types of text justification. It can be used to
99+
* align text to the left, right, or center of a container.
100+
*/
101+
private final Justification justification;
102+
103+
/** The borderColor variable represents the color used as the border of a FlatImageLabel. */
104+
private final Color borderColor;
105+
106+
/** The borderSize variable represents the size of the border for a FlatImageLabel. */
107+
private final int borderWidth;
108+
109+
/** The borderArc variable represents the size of the border arc for a FlatImageLabel. */
110+
private final int borderArc;
111+
112+
/**
113+
* The FlatImageLabel class represents an image label with customizable properties such as
114+
* padding, colors, font, and justification. It can be used to create labels for images in various
115+
* containers.
116+
*
117+
* @param padX the horizontal padding value for the label.
118+
* @param padY the vertical padding value for the label.
119+
* @param foreground the color value for the foreground of the label.
120+
* @param background the color value for the background of the label.
121+
* @param borderColor the color value for the border of the label.
122+
* @param font the font used for rendering text in the label.
123+
* @param justification the type of text justification used for the label.
124+
* @param borderWidth the size of the border for the label.
125+
*/
126+
public FlatImageLabel(
127+
int padX,
128+
int padY,
129+
Color foreground,
130+
Color background,
131+
Color borderColor,
132+
Font font,
133+
Justification justification,
134+
int borderWidth,
135+
int borderArc) {
136+
this.padX = padX;
137+
this.padY = padY;
138+
this.foreground = foreground;
139+
this.background = background;
140+
this.font = font;
141+
this.justification = justification;
142+
this.borderColor = borderColor;
143+
this.borderWidth = borderWidth;
144+
this.borderArc = borderArc;
145+
}
146+
147+
/**
148+
* Calculates the dimensions required to display the given string using the specified graphics
149+
* context.
150+
*
151+
* @param graphics2D the graphics context used for rendering
152+
* @param string the string to be displayed
153+
* @return the dimensions required to display the string with padding
154+
*/
155+
public Dimension getDimensions(Graphics2D graphics2D, String string) {
156+
var g2d = (Graphics2D) graphics2D.create();
157+
g2d.setFont(font);
158+
var fm = g2d.getFontMetrics();
159+
int strWidth = SwingUtilities.computeStringWidth(fm, string);
160+
int strHeight = fm.getHeight();
161+
return new Dimension(
162+
strWidth + padX * 2 + borderWidth * 2, strHeight + padY * 2 + borderWidth * 2);
163+
}
164+
165+
/**
166+
* Renders a string with customizable properties such as font, padding, colors, and justification
167+
* using the specified graphics context.
168+
*
169+
* @param graphics2D the graphics context used for rendering
170+
* @param x the x-coordinate of the top-left corner of the rendered string
171+
* @param y the y-coordinate of the top-left corner of the rendered string
172+
* @param string the string to be rendered
173+
* @return a Rectangle representing the dimensions and position of the rendered string with
174+
* padding
175+
*/
176+
public Rectangle render(Graphics2D graphics2D, int x, int y, String string) {
177+
var g2d = (Graphics2D) graphics2D.create();
178+
g2d.setFont(font);
179+
var fm = g2d.getFontMetrics();
180+
int strWidth = SwingUtilities.computeStringWidth(fm, string);
181+
int strHeight = fm.getAscent() - fm.getDescent() - fm.getLeading();
182+
183+
var dim = getDimensions(g2d, string);
184+
int width = (int) dim.getWidth();
185+
int height = (int) dim.getHeight();
186+
187+
var bounds = new Rectangle(x, y, width, height);
188+
189+
int stringY = y + height / 2 + strHeight / 2;
190+
int stringX =
191+
switch (justification) {
192+
case Left -> x + padY;
193+
case Right -> width - strWidth - padX;
194+
case Center -> x + padX + (width - strWidth) / 2 - padX;
195+
};
196+
197+
var labelRect = new RoundRectangle2D.Float(x, y, width - 1, height - 1, borderArc, borderArc);
198+
g2d.setBackground(background);
199+
g2d.setColor(background);
200+
g2d.fill(labelRect);
201+
g2d.setColor(foreground);
202+
g2d.drawString(string, stringX, stringY);
203+
if (borderWidth > 0) {
204+
g2d.setStroke(new BasicStroke(borderWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
205+
g2d.setColor(borderColor);
206+
g2d.draw(labelRect);
207+
}
208+
209+
return bounds;
210+
}
211+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/*
2+
* This software Copyright by the RPTools.net development team, and
3+
* licensed under the Affero GPL Version 3 or, at your option, any later
4+
* version.
5+
*
6+
* MapTool Source Code is distributed in the hope that it will be
7+
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
8+
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9+
*
10+
* You should have received a copy of the GNU Affero General Public
11+
* License * along with this source Code. If not, please visit
12+
* <http://www.gnu.org/licenses/> and specifically the Affero license
13+
* text at <http://www.gnu.org/licenses/agpl.html>.
14+
*/
15+
package net.rptools.maptool.client.swing.label;
16+
17+
import java.awt.Color;
18+
import net.rptools.maptool.client.AppPreferences;
19+
import net.rptools.maptool.client.AppStyle;
20+
import net.rptools.maptool.client.swing.label.FlatImageLabel.Justification;
21+
import net.rptools.maptool.model.Label;
22+
import net.rptools.maptool.model.Token;
23+
import net.rptools.maptool.model.Token.Type;
24+
25+
/**
26+
* The FlatImageLabelFactory class is responsible for creating instances of FlatImageLabel objects.
27+
* It provides methods to customize the labels based on different parameters.
28+
*/
29+
public class FlatImageLabelFactory {
30+
31+
/** The singleton instance of the FlatImageLabelFactory class for NPC labels */
32+
private final FlatImageLabel npcImageLabel;
33+
34+
/** The singleton instance of the FlatImageLabelFactory class for PC labels */
35+
private final FlatImageLabel pcImageLabel;
36+
37+
/** The singleton instance of the FlatImageLabelFactory class for non-visible token labels */
38+
private final FlatImageLabel nonVisibleImageLabel;
39+
40+
/** Creates a new instance of the FlatImageLabelFactory class. */
41+
public FlatImageLabelFactory() {
42+
var npcBackground = AppPreferences.getNPCMapLabelBG();
43+
var npcForeground = AppPreferences.getNPCMapLabelFG();
44+
var npcBorder = AppPreferences.getNPCMapLabelBorder();
45+
var pcBackground = AppPreferences.getPCMapLabelBG();
46+
var pcForeground = AppPreferences.getPCMapLabelFG();
47+
var pcBorder = AppPreferences.getPCMapLabelBorder();
48+
var nonVisBackground = AppPreferences.getNonVisMapLabelBG();
49+
var nonVisForeground = AppPreferences.getNonVisMapLabelFG();
50+
var nonVisBorder = AppPreferences.getNonVisMapLabelBorder();
51+
int fontSize = AppPreferences.getMapLabelFontSize();
52+
var font = AppStyle.labelFont.deriveFont(AppStyle.labelFont.getStyle(), fontSize);
53+
boolean showBorder = AppPreferences.getShowMapLabelBorder();
54+
int borderWidth = showBorder ? AppPreferences.getMapLabelBorderWidth() : 0;
55+
int borderArc = AppPreferences.getMapLabelBorderArc();
56+
57+
npcImageLabel =
58+
new FlatImageLabel(
59+
4,
60+
4,
61+
npcForeground,
62+
npcBackground,
63+
npcBorder,
64+
font,
65+
Justification.Center,
66+
borderWidth,
67+
borderArc);
68+
pcImageLabel =
69+
new FlatImageLabel(
70+
4,
71+
4,
72+
pcForeground,
73+
pcBackground,
74+
pcBorder,
75+
font,
76+
Justification.Center,
77+
borderWidth,
78+
borderArc);
79+
nonVisibleImageLabel =
80+
new FlatImageLabel(
81+
4,
82+
4,
83+
nonVisForeground,
84+
nonVisBackground,
85+
nonVisBorder,
86+
font,
87+
Justification.Center,
88+
borderWidth,
89+
borderArc);
90+
}
91+
92+
/**
93+
* Retrieves the appropriate map image label based on the provided token.
94+
*
95+
* @param token The token representing the entity on the map.
96+
* @return The map image label corresponding to the token type, and/or visibility.
97+
*/
98+
public FlatImageLabel getMapImageLabel(Token token) {
99+
if (!token.isVisible()) {
100+
return nonVisibleImageLabel;
101+
} else if (token.getType() == Type.NPC) {
102+
return npcImageLabel;
103+
} else {
104+
return pcImageLabel;
105+
}
106+
}
107+
108+
/**
109+
* Retrieves the map image label based on the provided label.
110+
*
111+
* @param label The label containing the properties for the map image label.
112+
* @return The map image label with the specified properties.
113+
*/
114+
public FlatImageLabel getMapImageLabel(Label label) {
115+
var font = AppStyle.labelFont.deriveFont(AppStyle.labelFont.getStyle(), label.getFontSize());
116+
var bg = label.isShowBackground() ? label.getBackgroundColor() : new Color(0, 0, 0, 0);
117+
int borderSize = label.isShowBorder() ? label.getBorderWidth() : 0;
118+
return new FlatImageLabel(
119+
4,
120+
4,
121+
label.getForegroundColor(),
122+
bg,
123+
label.getBorderColor(),
124+
font,
125+
Justification.Center,
126+
borderSize,
127+
label.getBorderArc());
128+
}
129+
}

0 commit comments

Comments
 (0)