feat(jui): new multiline container item tooltips

Backported from Java Edition 1.3.x
This replaces the old non-functional tooltips
This commit is contained in:
Sally Knight 2026-03-15 18:29:09 +03:00
parent 1837452f24
commit fae7ebe7fa

View file

@ -93,22 +93,143 @@ void AbstractContainerScreen::render(int xm, int ym, float a)
renderLabels();
if (inventory->getCarried() == NULL && hoveredSlot != NULL && hoveredSlot->hasItem())
{
// 4jcraft: newer tooltips backported from java edition 1.3.x (MCP 7.x)
if (inventory->getCarried() == NULL && hoveredSlot != NULL &&
hoveredSlot->hasItem()) {
std::shared_ptr<ItemInstance> item = hoveredSlot->getItem();
// std::wstring elementName = trimString(Language::getInstance()->getElementName(hoveredSlot->getItem()->getDescriptionId()));
std::wstring elementName = L"";
// std::wstring elementName =
// trimString(Language::getInstance()->getElementName(hoveredSlot->getItem()->getDescriptionId()));
std::vector<std::wstring> elementName;
std::vector<std::wstring>* tooltipLines =
item->getHoverText(minecraft->player, false, elementName);
if (elementName.length() > 0)
{
int x = xm - xo + 12;
int y = ym - yo - 12;
int width = font->width(elementName);
fillGradient(x - 3, y - 3, x + width + 3, y + 8 + 3, 0xc0000000, 0xc0000000);
if (tooltipLines != NULL && tooltipLines->size() > 0) {
int tooltipWidth = 0;
std::vector<std::wstring> cleanedLines;
std::vector<int> lineColors;
font->drawShadow(elementName, x, y, 0xffffffff);
for (int lineIndex = 0; lineIndex < (int)tooltipLines->size();
++lineIndex) {
std::wstring rawLine = (*tooltipLines)[lineIndex];
std::wstring clean = L"";
int lineColor = 0xffffffff;
// 4jcraft: LCE is using HTML font elements for its tooltip
// colors, so make sure to parse them for parity w iggy UI
//
// examples would be enchantment books, potions and music
// discs
size_t fontPos = rawLine.find(L"<font");
if (fontPos != std::wstring::npos) {
size_t colorPos = rawLine.find(L"color=\"", fontPos);
if (colorPos != std::wstring::npos) {
colorPos += 7;
size_t colorEnd = rawLine.find(L'"', colorPos);
if (colorEnd != std::wstring::npos) {
std::wstring colorStr =
rawLine.substr(colorPos, colorEnd - colorPos);
if (!colorStr.empty() && colorStr[0] == L'#') {
colorStr = colorStr.substr(1);
}
if (!colorStr.empty()) {
wchar_t* endPtr;
long hexColor =
wcstol(colorStr.c_str(), &endPtr, 16);
if (*endPtr == L'\0') {
lineColor = 0xff000000 | (int)hexColor;
}
}
}
}
}
bool inTag = false;
for (wchar_t currentChar : rawLine) {
if (currentChar == L'<') {
inTag = true;
} else if (currentChar == L'>') {
inTag = false;
} else if (!inTag) {
clean += currentChar;
}
}
cleanedLines.push_back(clean);
lineColors.push_back(lineColor);
int lineWidth = font->width(clean);
if (lineWidth > tooltipWidth) {
tooltipWidth = lineWidth;
}
}
int tooltipX = xm - xo + 12;
int tooltipY = ym - yo - 12;
int tooltipHeight = 8;
if (tooltipLines->size() > 1) {
tooltipHeight += 2 + (tooltipLines->size() - 1) * 10;
}
int bgColor = 0xf0100010;
fillGradient(tooltipX - 3, tooltipY - 4,
tooltipX + tooltipWidth + 3, tooltipY - 3, bgColor,
bgColor);
fillGradient(tooltipX - 3, tooltipY + tooltipHeight + 3,
tooltipX + tooltipWidth + 3,
tooltipY + tooltipHeight + 4, bgColor, bgColor);
fillGradient(tooltipX - 3, tooltipY - 3,
tooltipX + tooltipWidth + 3,
tooltipY + tooltipHeight + 3, bgColor, bgColor);
fillGradient(tooltipX - 4, tooltipY - 3, tooltipX - 3,
tooltipY + tooltipHeight + 3, bgColor, bgColor);
fillGradient(tooltipX + tooltipWidth + 3, tooltipY - 3,
tooltipX + tooltipWidth + 4,
tooltipY + tooltipHeight + 3, bgColor, bgColor);
int borderStart = 0x505000ff;
int borderFinish =
(borderStart & 0xfefefe) >> 1 | borderStart & 0xff000000;
fillGradient(tooltipX - 3, (tooltipY - 3) + 1, (tooltipX - 3) + 1,
(tooltipY + tooltipHeight + 3) - 1, borderStart,
borderFinish);
fillGradient(tooltipX + tooltipWidth + 2, (tooltipY - 3) + 1,
tooltipX + tooltipWidth + 3,
(tooltipY + tooltipHeight + 3) - 1, borderStart,
borderFinish);
fillGradient(tooltipX - 3, tooltipY - 3,
tooltipX + tooltipWidth + 3, (tooltipY - 3) + 1,
borderStart, borderStart);
fillGradient(tooltipX - 3, tooltipY + tooltipHeight + 2,
tooltipX + tooltipWidth + 3,
tooltipY + tooltipHeight + 3, borderFinish,
borderFinish);
int currentY = tooltipY;
for (int lineIndex = 0; lineIndex < (int)tooltipLines->size();
++lineIndex) {
std::wstring& currentLine = cleanedLines[lineIndex];
int textColor;
if (lineIndex == 0) {
textColor = app.GetHTMLColour(item->getRarity()->color);
} else {
textColor = (lineColors[lineIndex] != 0xffffffff)
? lineColors[lineIndex]
: 0xffaaaaaa;
}
font->drawShadow(currentLine, tooltipX, currentY, textColor);
if (lineIndex == 0) {
currentY += 2;
}
currentY += 10;
}
}
}
glPopMatrix();