diff --git a/Source/UI/Lists/UIScrollBar.cpp b/Source/UI/Lists/UIScrollBar.cpp index 98a5086d..fd1eebb7 100644 --- a/Source/UI/Lists/UIScrollBar.cpp +++ b/Source/UI/Lists/UIScrollBar.cpp @@ -1119,6 +1119,140 @@ void UIChatHisBox::ShiftItemTags() { } } +// OFFSET: 0x0087E9B0 +// FUNCTION: fn_11267 +int UITreeView::LayoutNodes(std::list& 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(nodes.size()) <= 0) { + return y; + } + + for (std::list::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(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(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) { diff --git a/Source/UI/Lists/UITreeView.h b/Source/UI/Lists/UITreeView.h index 422a0712..efc265ea 100644 --- a/Source/UI/Lists/UITreeView.h +++ b/Source/UI/Lists/UITreeView.h @@ -4,6 +4,8 @@ #include "UI/Window/UIWindow.h" #include +#include +#include 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 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& nodes, int x, int y); protected: /* 007C */ UIScrollBar* verticalBar;