Decompile fn_11267 (UITreeView::LayoutNodes)

Batch #8135 by eAthena: 0 byte-identical, 1 confirmed by peer review.

- fn_11267 UITreeView::LayoutNodes: logic confirmed by peer review

Peer-reviewed-by: ragnarok-clanker, Yommy, secret
Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
This commit is contained in:
ragnarok-clanker 2026-10-31 14:38:18 +00:00
commit 7ec3dcbdaa
2 changed files with 140 additions and 1 deletions

View file

@ -1119,6 +1119,140 @@ void UIChatHisBox::ShiftItemTags() {
}
}
// OFFSET: 0x0087E9B0
// FUNCTION: fn_11267
int UITreeView::LayoutNodes(std::list<UITreeNode*>& nodes, int x, int y) {
int rowHeight = 0;
const int first = this->unknown_00A8;
const int last = this->geometry.height / this->itemHeight + first;
const int gap = this->itemPadding - 2;
if (static_cast<int>(nodes.size()) <= 0) {
return y;
}
for (std::list<UITreeNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it, ++this->itemCount) {
UITreeNode* node = *it;
int labelX = x;
if (node->collapseButton) {
labelX = node->collapseButton->BitmapWidth() + gap + x;
}
int bottom = y;
if (this->itemCount >= first && this->itemCount < last) {
if (node->icon > -1) {
auto* bitmap = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve(node->icons[node->icon].c_str())));
bottom = bitmap->image.height + y;
if (bottom >= this->geometry.height) {
continue;
}
this->DrawBitmap(labelX, y, &bitmap->image, true);
labelX += bitmap->image.width + gap;
}
if (bottom >= this->geometry.height) {
continue;
}
UITVTextButton* label = node->labelButton;
label->unknown_00B4 = 0;
label->Invalidate();
if (this->unknown_0088 && this->unknown_0088 == node) {
node->labelButton->unknown_00B4 = 1;
node->labelButton->Invalidate();
}
label = node->labelButton;
label->unknown_00B5 = 0;
label->m_highlightColor = 0;
label->Invalidate();
if (this->unknown_00AC && this->unknown_008C && this->unknown_0090 && this->unknown_00B0) {
if (this->unknown_0090 == node) {
label = node->labelButton;
label->unknown_00B5 = 1;
label->m_highlightColor = this->unknown_00B0;
label->Invalidate();
}
if (node->unknown_0170 && node->unknown_0170->labelButton && node->unknown_0170->labelButton->unknown_00B5) {
label = node->labelButton;
label->m_highlightColor = this->unknown_00B0;
label->unknown_00B5 = 1;
label->Invalidate();
}
}
int maxWidth = this->geometry.width - labelX - 2;
if (this->verticalOverflow) {
maxWidth -= this->verticalBar->geometry.width;
}
node->labelButton->Move(labelX, y + 2);
label = node->labelButton;
const int height = label->geometry.height;
if (maxWidth != label->geometry.width && std::strcmp(label->label.c_str(), "") != 0) {
label->unknown_00DC = label->label;
int width;
if (label->geometry.width > maxWidth) {
const char* fitted = label->ClipTextToWidth(label->label.c_str(), maxWidth - 2, label->m_fontFamily, label->m_fontHeight, label->m_outlined);
label->unknown_00DC = fitted;
width = label->m_border ? maxWidth + 2 : maxWidth;
} else {
width = label->TextWidth(
label->m_buttonContext->fonts, label->m_buttonContext->locale, label->label.c_str(), 0, label->m_fontFamily, label->m_fontHeight,
label->m_outlined, 0
) +
2;
width = label->m_border ? width + 2 : width;
}
label->UIWindow::Resize(width, height);
}
if (this->editNode == node) {
node->labelButton->Move(-100, -100);
this->edit->Resize(node->labelButton->geometry.width, node->labelButton->geometry.height);
this->edit->Move(labelX, y + 2);
}
rowHeight = node->labelButton->geometry.height + this->itemPadding;
this->itemHeight = std::max(this->itemHeight, rowHeight);
}
if (bottom >= this->geometry.height) {
continue;
}
if (node->expanded == 0) {
if (this->itemCount >= first && this->itemCount < last) {
if (node->expandButton) {
node->expandButton->Move(x, y + 4);
}
y += rowHeight;
}
} else if (node->expanded == 1) {
if (this->itemCount >= first && this->itemCount < last) {
if (node->collapseButton) {
node->collapseButton->Move(x, y + 4);
}
y += rowHeight;
bottom += rowHeight;
}
if (static_cast<int>(node->children.size()) > 0 && bottom < this->geometry.height) {
if (node->collapseButton) {
x += node->collapseButton->BitmapWidth() + gap;
}
const int next = this->LayoutNodes(node->children, x, y);
if (this->itemCount >= first && this->itemCount < last) {
y = next;
}
if (node->collapseButton) {
x -= node->collapseButton->BitmapWidth() + gap;
}
}
}
}
return y;
}
// OFFSET: 0x0087EF30
// FUNCTION: fn_11268
void UIChatHisBox::PlaceItemTags(int line) {

View file

@ -4,6 +4,8 @@
#include "UI/Window/UIWindow.h"
#include <list>
#include <string>
#include <vector>
class UIScrollBar;
class UIEditCtrl2;
@ -15,7 +17,7 @@ struct UIButtonContext;
struct UITreeNode {
/* 0000 */ int id;
/* 0004 */ int expanded;
/* 0008 */ unsigned char unknown_0008[0x4];
/* 0008 */ int icon;
/* 000C */ char name[0x100];
/* 010C */ unsigned char unknown_010C[0x5E];
/* 016A */ unsigned char draggable;
@ -26,6 +28,8 @@ struct UITreeNode {
/* 0178 */ UITVBitmapButton* collapseButton;
/* 017C */ UITVTextButton* labelButton;
/* 0180 */ std::list<UITreeNode*> children;
/* 0188 */ std::string* icons;
/* 018C */ unsigned char unknown_018C[0x8];
};
#if defined(_WIN32) && !defined(_WIN64)
@ -49,6 +53,7 @@ public:
int RemoveChildNode(UITreeNode* parent, int id, bool keepButtons);
void AddNodeButtons(UITreeNode* node, int id);
void AddNodeLabel(UITreeNode* node, int id);
int LayoutNodes(std::list<UITreeNode*>& nodes, int x, int y);
protected:
/* 007C */ UIScrollBar* verticalBar;