Skip to content

Commit bb27ccc

Browse files
authored
Merge pull request #418 from BentoBoxWorld/feat/340-default-text-color
Add default colour for challenge description and reward text
2 parents f699c90 + 003b90b commit bb27ccc

5 files changed

Lines changed: 153 additions & 4 deletions

File tree

src/main/java/world/bentobox/challenges/config/Settings.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,20 @@ public class Settings implements ConfigObject
123123
@ConfigEntry(path = "gui-settings.open-anywhere")
124124
private boolean openAnywhere = false;
125125

126+
@ConfigComment("")
127+
@ConfigComment("Default colour applied to every line of a challenge's own description text, so you")
128+
@ConfigComment("do not have to prefix each challenge with the same colour. Uses '&' colour codes or")
129+
@ConfigComment("hex (e.g. '&b' or '&#55FFFF'). Leave empty for no default. A colour written in the")
130+
@ConfigComment("description itself still overrides this. Does not affect per-challenge locale overrides.")
131+
@ConfigEntry(path = "gui-settings.description-color")
132+
private String descriptionColor = "";
133+
134+
@ConfigComment("")
135+
@ConfigComment("Default colour applied to every line of a challenge's own reward text (both first-time")
136+
@ConfigComment("and repeat reward text). Same format as description-color. Leave empty for no default.")
137+
@ConfigEntry(path = "gui-settings.reward-text-color")
138+
private String rewardTextColor = "";
139+
126140

127141
@ConfigComment("")
128142
@ConfigComment("This allows to change default locked level icon. This option may be")
@@ -743,4 +757,48 @@ public void setOpenAnywhere(boolean openAnywhere)
743757
{
744758
this.openAnywhere = openAnywhere;
745759
}
760+
761+
762+
/**
763+
* Returns the default colour applied to challenge description text.
764+
*
765+
* @return the description colour code, or an empty string for no default.
766+
*/
767+
public String getDescriptionColor()
768+
{
769+
return descriptionColor;
770+
}
771+
772+
773+
/**
774+
* Sets the default colour applied to challenge description text.
775+
*
776+
* @param descriptionColor the colour code (e.g. "&b" or "&#55FFFF"), or empty for none.
777+
*/
778+
public void setDescriptionColor(String descriptionColor)
779+
{
780+
this.descriptionColor = descriptionColor;
781+
}
782+
783+
784+
/**
785+
* Returns the default colour applied to challenge reward text.
786+
*
787+
* @return the reward text colour code, or an empty string for no default.
788+
*/
789+
public String getRewardTextColor()
790+
{
791+
return rewardTextColor;
792+
}
793+
794+
795+
/**
796+
* Sets the default colour applied to challenge reward text.
797+
*
798+
* @param rewardTextColor the colour code (e.g. "&b" or "&#55FFFF"), or empty for none.
799+
*/
800+
public void setRewardTextColor(String rewardTextColor)
801+
{
802+
this.rewardTextColor = rewardTextColor;
803+
}
746804
}

src/main/java/world/bentobox/challenges/panel/CommonPanel.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,11 @@ protected List<String> generateChallengeDescription(Challenge challenge, @Nullab
143143
String description = this.user
144144
.getTranslationOrNothing(Constants.CHALLENGES_CHALLENGES + challenge.getUniqueId() + ".description");
145145
if (description.isEmpty()) {
146-
// Combine the challenge description list into a single string and translate color codes
147-
description = Util.translateColorCodes(String.join("\n", challenge.getDescription()));
146+
// Combine the challenge description list into a single string, apply the configured
147+
// default colour to each line, and translate color codes.
148+
description = Util.translateColorCodes(Utils.applyDefaultColor(
149+
String.join("\n", challenge.getDescription()),
150+
this.addon.getChallengesSettings().getDescriptionColor()));
148151
}
149152
// Replace any [label] placeholder with the actual top label
150153
description = description.replace("[label]", this.topLabel);
@@ -707,7 +710,9 @@ private String generateRepeatReward(Challenge challenge) {
707710
.getTranslationOrNothing(Constants.CHALLENGES_CHALLENGES + challenge.getUniqueId() + ".repeat-reward-text");
708711

709712
if (rewardText.isEmpty()) {
710-
rewardText = wrapToWidth(Util.translateColorCodes(String.join("\n", challenge.getRepeatRewardText())), 30);
713+
rewardText = wrapToWidth(Util.translateColorCodes(Utils.applyDefaultColor(
714+
String.join("\n", challenge.getRepeatRewardText()),
715+
this.addon.getChallengesSettings().getRewardTextColor())), 30);
711716
}
712717

713718
return this.user.getTranslationOrNothing(reference + "lore", Constants.PARAMETER_TEXT, rewardText, Constants.PARAMETER_ITEMS, items,
@@ -786,7 +791,9 @@ private String generateReward(Challenge challenge) {
786791
.getTranslationOrNothing(Constants.CHALLENGES_CHALLENGES + challenge.getUniqueId() + ".reward-text");
787792

788793
if (rewardText.isEmpty()) {
789-
rewardText = wrapToWidth(Util.translateColorCodes(String.join("\n", challenge.getRewardText())), 30);
794+
rewardText = wrapToWidth(Util.translateColorCodes(Utils.applyDefaultColor(
795+
String.join("\n", challenge.getRewardText()),
796+
this.addon.getChallengesSettings().getRewardTextColor())), 30);
790797
}
791798

792799
return this.user.getTranslationOrNothing(reference + "lore", Constants.PARAMETER_TEXT, rewardText, Constants.PARAMETER_ITEMS, items,

src/main/java/world/bentobox/challenges/utils/Utils.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,4 +1047,42 @@ public static String parseDuration(Duration duration, User user)
10471047

10481048
return returnString;
10491049
}
1050+
1051+
1052+
/**
1053+
* Prefixes every line of the given text with a default colour code so the colour applies
1054+
* to each rendered lore line, not only the first (each lore line is rendered
1055+
* independently). A colour written at the start of a line still overrides the default,
1056+
* because a later colour code wins over an earlier one. The text is returned unchanged
1057+
* when the colour is blank or the text is empty.
1058+
*
1059+
* <p>The colour is applied before {@code Util.translateColorCodes}, so it uses the same
1060+
* '&amp;' colour codes (or hex, e.g. {@code &#55FFFF}) as the challenge text itself.
1061+
*
1062+
* @param text the text whose lines should be coloured (may contain '\n').
1063+
* @param color the default colour code; blank means no change.
1064+
* @return the text with the colour prefixed to each line.
1065+
*/
1066+
public static String applyDefaultColor(String text, String color)
1067+
{
1068+
if (color == null || color.isBlank() || text == null || text.isEmpty())
1069+
{
1070+
return text;
1071+
}
1072+
1073+
String[] lines = text.split("\n", -1);
1074+
StringBuilder builder = new StringBuilder(text.length() + lines.length * color.length());
1075+
1076+
for (int i = 0; i < lines.length; i++)
1077+
{
1078+
if (i > 0)
1079+
{
1080+
builder.append('\n');
1081+
}
1082+
1083+
builder.append(color).append(lines[i]);
1084+
}
1085+
1086+
return builder.toString();
1087+
}
10501088
}

src/main/resources/config.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,16 @@ gui-settings:
8080
# Note: Challenges completion still requires being on the island when world protection is enabled.
8181
open-anywhere: false
8282
#
83+
# Default colour applied to every line of a challenge's own description text, so you
84+
# do not have to prefix each challenge with the same colour. Uses '&' colour codes or
85+
# hex (e.g. '&b' or '&#55FFFF'). Leave empty for no default. A colour written in the
86+
# description itself still overrides this. Does not affect per-challenge locale overrides.
87+
description-color: ''
88+
#
89+
# Default colour applied to every line of a challenge's own reward text (both first-time
90+
# and repeat reward text). Same format as description-color. Leave empty for no default.
91+
reward-text-color: ''
92+
#
8393
# This allows to change default locked level icon. This option may be
8494
# overwritten by each challenge level. If challenge level has specified
8595
# their locked level icon, then it will be used, instead of this one.

src/test/java/world/bentobox/challenges/utils/UtilsTest.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,40 @@ void testGetPreviousValue() {
156156
assertEquals(VisibilityMode.VISIBLE, Utils.getPreviousValue(VisibilityMode.values(), VisibilityMode.HIDDEN));
157157
assertEquals(VisibilityMode.HIDDEN, Utils.getPreviousValue(VisibilityMode.values(), VisibilityMode.TOGGLEABLE));
158158
}
159+
160+
@Test
161+
void testApplyDefaultColorBlankColorReturnsTextUnchanged() {
162+
assertEquals("Hello", Utils.applyDefaultColor("Hello", ""));
163+
assertEquals("Hello", Utils.applyDefaultColor("Hello", " "));
164+
assertEquals("Hello", Utils.applyDefaultColor("Hello", null));
165+
}
166+
167+
@Test
168+
void testApplyDefaultColorEmptyOrNullTextReturnedUnchanged() {
169+
assertEquals("", Utils.applyDefaultColor("", "&b"));
170+
assertNull(Utils.applyDefaultColor(null, "&b"));
171+
}
172+
173+
@Test
174+
void testApplyDefaultColorSingleLinePrefixed() {
175+
assertEquals("&bHello", Utils.applyDefaultColor("Hello", "&b"));
176+
}
177+
178+
@Test
179+
void testApplyDefaultColorPrefixesEveryLine() {
180+
assertEquals("&bLine1\n&bLine2\n&bLine3",
181+
Utils.applyDefaultColor("Line1\nLine2\nLine3", "&b"));
182+
}
183+
184+
@Test
185+
void testApplyDefaultColorPreservesBlankLines() {
186+
// Blank lines still get the prefix, and no trailing/leading lines are dropped.
187+
assertEquals("&bLine1\n&b\n&bLine2",
188+
Utils.applyDefaultColor("Line1\n\nLine2", "&b"));
189+
}
190+
191+
@Test
192+
void testApplyDefaultColorSupportsHexColor() {
193+
assertEquals("&#55FFFFHello", Utils.applyDefaultColor("Hello", "&#55FFFF"));
194+
}
159195
}

0 commit comments

Comments
 (0)