Skip to content

Commit

Permalink
Parse colored text for level name
Browse files Browse the repository at this point in the history
  • Loading branch information
kbinani committed Jun 22, 2024
1 parent 1b0b4fe commit 9ca7662
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 9 deletions.
103 changes: 95 additions & 8 deletions Source/GameDirectory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ class GameDirectory {

public:
juce::File fDirectory;
juce::String fLevelName;
juce::AttributedString fLevelName;
juce::Image fIcon;
std::optional<juce::Time> fLastPlayed;
Edition fEdition;

static std::optional<GameDirectory> Open(juce::File directory) {
GameDirectory gd;
gd.fLevelName = directory.getFileName();
gd.fLevelName.append(directory.getFileName(), juce::Colours::white);
gd.fDirectory = directory;
if (directory.getChildFile("db").exists()) {
gd.fEdition = Edition::Bedrock;
if (directory.getChildFile("levelname.txt").existsAsFile()) {
if (auto stream = directory.getChildFile("levelname.txt").createInputStream(); stream && stream->openedOk()) {
auto name = stream->readEntireStreamAsString().trim();
if (name.isNotEmpty()) {
gd.fLevelName = name;
gd.fLevelName = MakeAttributedString(name);
}
}
}
Expand Down Expand Up @@ -50,7 +50,7 @@ class GameDirectory {
if (auto name = data->string(u8"LevelName"); name) {
auto n = juce::String::fromUTF8(name->c_str());
if (n.isNotEmpty()) {
gd.fLevelName = n;
gd.fLevelName = MakeAttributedString(n);
}
}
if (auto lastPlayed = data->int64(u8"LastPlayed"); lastPlayed) {
Expand Down Expand Up @@ -109,18 +109,29 @@ class GameDirectory {
int lineHeight = bounds.getHeight() / 3;
auto levelNameArea = bounds.removeFromTop(lineHeight);
g.setColour(selected ? textColorOn : textColorOff);
auto levelName = fLevelName;
juce::AttributedString levelName;
levelName.append(fLevelName);
if (!omitEdition) {
switch (fEdition) {
case Edition::Java:
levelName += " (Java)";
levelName.append(" (Java)", juce::Colours::white);
break;
case Edition::Bedrock:
levelName += " (Bedrock)";
levelName.append(" (Bedrock)", juce::Colours::white);
break;
}
}
g.drawFittedText(levelName, levelNameArea, juce::Justification::centredLeft, 1);
levelName.setJustification(juce::Justification::centredLeft);
auto text = levelName.getText();
float width = g.getCurrentFont().getStringWidthFloat(levelName.getText());
g.saveState();
g.addTransform(juce::AffineTransform::translation(levelNameArea.getX(), levelNameArea.getY()));
if (width > 0) {
float scale = std::min<float>(1, levelNameArea.getWidth() / width);
g.addTransform(juce::AffineTransform().scaled(scale, 1));
}
levelName.draw(g, juce::Rectangle<float>(0, 0, std::numeric_limits<float>::max() * 0.5f, levelNameArea.getHeight()));
g.restoreState();

auto directoryNameArea = bounds.removeFromTop(lineHeight);
g.setColour(juce::Colours::grey);
Expand Down Expand Up @@ -176,6 +187,82 @@ class GameDirectory {
int minute = t.getMinutes();
return juce::String(year) + "/" + juce::String::formatted("%02d", month) + "/" + juce::String::formatted("%02d", day) + " " + juce::String(hour) + ":" + juce::String::formatted("%02d", minute);
}

static juce::AttributedString MakeAttributedString(juce::String const &s) {
juce::AttributedString r;
int offset = 0;
juce::Colour color = juce::Colours::white;
while (true) {
int index = s.indexOf(offset, juce::String(u8"\u00a7"));
if (index < 0) {
break;
}
r.append(s.substring(offset, index), color);
auto op = s.substring(index + 1, index + 2);
offset = index + 2;
if (op == "0") {
color = juce::Colour(0x00, 0x00, 0x00);
} else if (op == "1") {
color = juce::Colour(0x00, 0x00, 0xaa);
} else if (op == "2") {
color = juce::Colour(0x00, 0xAA, 0x00);
} else if (op == "3") {
color = juce::Colour(0x00, 0xAA, 0xAA);
} else if (op == "4") {
color = juce::Colour(0xAA, 0x00, 0x00);
} else if (op == "5") {
color = juce::Colour(0xAA, 0x00, 0xAA);
} else if (op == "6") {
color = juce::Colour(0xFF, 0xAA, 0x00);
} else if (op == "7") {
color = juce::Colour(0xAA, 0xAA, 0xAA);
} else if (op == "8") {
color = juce::Colour(0x55, 0x55, 0x55);
} else if (op == "9") {
color = juce::Colour(0x55, 0x55, 0xFF);
} else if (op == "a") {
color = juce::Colour(0x55, 0xFF, 0x55);
} else if (op == "b") {
color = juce::Colour(0x55, 0xFF, 0xFF);
} else if (op == "c") {
color = juce::Colour(0xFF, 0x55, 0x55);
} else if (op == "d") {
color = juce::Colour(0xFF, 0x55, 0xFF);
} else if (op == "e") {
color = juce::Colour(0xFF, 0xFF, 0x55);
} else if (op == "f") {
color = juce::Colour(0xFF, 0xFF, 0xFF);
} else if (op == "g") {
color = juce::Colour(221, 214, 5);
} else if (op == "h") {
color = juce::Colour(227, 212, 209);
} else if (op == "i") {
color = juce::Colour(206, 202, 202);
} else if (op == "j") {
color = juce::Colour(68, 58, 59);
} else if (op == "m") {
color = juce::Colour(151, 22, 7);
} else if (op == "n") {
color = juce::Colour(180, 104, 77);
} else if (op == "p") {
color = juce::Colour(222, 177, 45);
} else if (op == "q") {
color = juce::Colour(17, 160, 54);
} else if (op == "s") {
color = juce::Colour(44, 186, 168);
} else if (op == "t") {
color = juce::Colour(33, 73, 123);
} else if (op == "u") {
color = juce::Colour(154, 92, 198);
} else if (op == "r") {
color = juce::Colours::white;
}
}
if (offset < s.length()) {
r.append(s.substring(offset), color);
}
return r;
}
};

} // namespace mcview
2 changes: 1 addition & 1 deletion Source/MainComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ class MainComponent : public juce::Component,
private:
void onSelect(GameDirectory const &gd) {
fMapViewComponent->setWorldDirectory(gd.fDirectory, Dimension::Overworld, gd.fEdition);
getTopLevelComponent()->setName(gd.fLevelName + " | " + gd.fDirectory.getFullPathName());
getTopLevelComponent()->setName(gd.fLevelName.getText() + " | " + gd.fDirectory.getFullPathName());
setBrowserOpened(false);
}

Expand Down

0 comments on commit 9ca7662

Please sign in to comment.