From c8faa3e5e1127dba21926f3e7fa8fcbfae25d74e Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Sat, 31 Oct 2026 02:48:00 +0000 Subject: [PATCH] Decompile fn_11563 (UITreeView::SendMsg) Batch #6953 by Romain: 0 byte-identical, 1 confirmed by peer review. - fn_11563 UITreeView::SendMsg: logic confirmed by peer review Peer-reviewed-by: eAthena, superintelligence, Landruca Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/UI/Lists/UIScrollBar.cpp | 195 ++++++++++++++++++++++++++++++++ Source/UI/Lists/UITreeView.h | 22 ++-- 2 files changed, 210 insertions(+), 7 deletions(-) diff --git a/Source/UI/Lists/UIScrollBar.cpp b/Source/UI/Lists/UIScrollBar.cpp index 68043d87..29b15cbb 100644 --- a/Source/UI/Lists/UIScrollBar.cpp +++ b/Source/UI/Lists/UIScrollBar.cpp @@ -13,6 +13,10 @@ #include "UI/Lists/UIImgMenu.h" #include "UI/Lists/UIListBoxEx.h" #include "UI/Lists/UITabControl.h" +#include "UI/Lists/UITreeView.h" +#include "UI/Buttons/UITVTextButton.h" +#include "UI/Buttons/UITVBitmapButton.h" +#include "UI/Window/InputFocus.h" #include "UI/Edit/UIEditCtrl.h" #include "UI/Edit/UIEditCtrl_Currency.h" #include "Render/Text/TextContext.h" @@ -22,6 +26,7 @@ #include "UI/Window/WindowDialogs.h" #include #include +#include // OFFSET: 0x0086E550 // FUNCTION: fn_11073 UIScrollBar::UIScrollBar(UIWindowContext& windows) @@ -901,3 +906,193 @@ void UIChatHisBox::ClearNaviLinks() { row = this->naviLinks.erase(row); } } + +// OFFSET: 0x0089ADD0 +// FUNCTION: fn_11563 +int UITreeView::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) { + switch (message) { + case 0: + if (sender == this->edit && this->editNode) { + this->SendMsg(nullptr, 110, 0, 1, 0, 0); + } + break; + case 7: + case 9: + case 10: { + this->HideNodes(this->root->children); + const int previous = this->unknown_00A8; + const int visible = this->geometry.height / this->itemHeight; + if (message == 9) { + this->unknown_00A8 = previous - visible + 1; + } else if (message == 10) { + this->unknown_00A8 = previous - 1 + visible; + } else { + this->unknown_00A8 = previous + static_cast(a); + } + + if (this->unknown_00A8 < 0) { + this->unknown_00A8 = 0; + } + + const int maximum = this->itemCount - visible; + if (this->unknown_00A8 > maximum) { + this->unknown_00A8 = maximum; + } + + this->verticalBar->position = this->unknown_00A8; + this->verticalBar->Invalidate(); + this->Invalidate(); + if (this->parent) { + this->parent->Invalidate(); + } + return this->unknown_00A8 - previous; + } + case 18: + if (this->verticalOverflow) { + this->SendMsg(this->verticalBar, 7, -1, 0, 0, 0); + } + break; + case 19: + if (this->verticalOverflow) { + this->SendMsg(this->verticalBar, 7, 1, 0, 0, 0); + } + break; + case 97: + this->unknown_0088 = reinterpret_cast(a); + if (a) { + this->parent->SendMsg(this, 97, a, sender->geometry.x + b, sender->geometry.height / 2 + sender->geometry.y, 0); + } + break; + case 98: + case 99: + case 100: + this->unknown_008C = nullptr; + this->unknown_0090 = nullptr; + this->unknown_0088 = reinterpret_cast(a); + if (!a) { + break; + } + + if (message == 99) { + this->parent->SendMsg(this, 99, a, sender->geometry.x + b, sender->geometry.height / 2 + sender->geometry.y, 0); + break; + } + + if (this->unknown_0088->children.size() != 0) { + this->HideNodes(this->root->children); + const int x = sender->geometry.x; + const int y = message == 98 ? sender->geometry.y - 6 : sender->geometry.y; + UIWindow* button; + if (this->unknown_0088->expanded == 0) { + this->unknown_0088->expanded = 1; + button = this->unknown_0088->collapseButton; + } else { + this->unknown_0088->expanded = 0; + button = this->unknown_0088->expandButton; + } + button->Move(x, y); + this->Invalidate(); + } + + if (message == 98) { + this->parent->SendMsg( + this, 98, reinterpret_cast(this->unknown_0088), sender->geometry.x + b, sender->geometry.height / 2 + sender->geometry.y, 0 + ); + } + + this->unknown_008C = nullptr; + this->unknown_0090 = nullptr; + break; + case 107: + this->unknown_008C = reinterpret_cast(a); + this->unknown_0088 = reinterpret_cast(a); + if (this->unknown_008C->draggable == 0) { + this->unknown_008C = nullptr; + } + break; + case 108: + this->m_context->cursor.Set(0, this->m_context->cursorTick); + if (this->unknown_008C && this->unknown_008C->id != a) { + UITreeNode* target = reinterpret_cast(a); + this->unknown_0090 = target; + if (target->container == 0) { + this->unknown_0090 = target->unknown_0170; + } + this->unknown_0090->expanded = 1; + this->Invalidate(); + } + break; + case 109: + if (sender == this->parent) { + this->unknown_0090 = nullptr; + } + + if (this->unknown_008C) { + if (this->unknown_008C->unknown_0170 == this->unknown_0090) { + break; + } + if (this->unknown_0090 && this->unknown_0090->unknown_0170 == this->unknown_008C) { + break; + } + + this->m_context->cursor.Set(2, this->m_context->cursorTick); + UITreeNode* node = this->unknown_008C; + UITVTextButton* label = node->labelButton; + this->RemoveChildNode(node->unknown_0170, node->id, true); + UITreeNode* previousParent = this->unknown_008C->unknown_0170; + this->unknown_008C->unknown_0170 = this->unknown_0090; + UITreeNode* target = this->unknown_0090 ? this->unknown_0090 : this->root; + target->children.push_back(this->unknown_008C); + this->unknown_008C->labelButton = label; + if (this->parent) { + this->parent->SendMsg( + this, 109, reinterpret_cast(this->unknown_008C), reinterpret_cast(this->unknown_0090), + reinterpret_cast(previousParent), 0 + ); + } + this->HideNodes(this->root->children); + } + + this->unknown_0088 = nullptr; + this->unknown_008C = nullptr; + this->unknown_0090 = nullptr; + this->Invalidate(); + break; + case 110: + if (b == 0) { + this->editNode = reinterpret_cast(a); + this->edit->maximum = c > 361 ? 361 : static_cast(c); + this->edit->SetText(this->editNode->name); + InputFocus focus{g_windowMgr.hoverWindow}; + focus.Set(this->edit); + this->Invalidate(); + } else if (b == 1) { + if (g_windowMgr.GetHoverWindow() == this->edit) { + const std::size_t length = std::strlen(this->edit->Text()); + if (this->parent) { + this->parent->SendMsg(this, 110, reinterpret_cast(this->edit->Text()), length + 1, 0, 0); + } + } + } else { + const int x = this->edit->geometry.x; + const int y = this->edit->geometry.y; + this->edit->Move(-100, -100); + if (c != 0) { + std::strcpy(this->editNode->name, this->edit->Text()); + this->editNode->labelButton->SetLabel(std::string(this->edit->Text())); + this->editNode->labelButton->ResizeToText(); + } + this->editNode->labelButton->Move(x, y); + this->editNode = nullptr; + } + break; + default: + break; + } + + return 0; +} + +// OFFSET: 0x0089E570 + +// OFFSET: 0x0089E6F0 diff --git a/Source/UI/Lists/UITreeView.h b/Source/UI/Lists/UITreeView.h index 8cdd9050..f999be76 100644 --- a/Source/UI/Lists/UITreeView.h +++ b/Source/UI/Lists/UITreeView.h @@ -13,9 +13,14 @@ class UITVTextButton; struct UIButtonContext; struct UITreeNode { - /* 0000 */ unsigned char unknown_0000[0xC]; + /* 0000 */ int id; + /* 0004 */ int expanded; + /* 0008 */ unsigned char unknown_0008[0x4]; /* 000C */ char name[0x100]; - /* 010C */ unsigned char unknown_010C[0x64]; + /* 010C */ unsigned char unknown_010C[0x5E]; + /* 016A */ unsigned char draggable; + /* 016B */ unsigned char container; + /* 016C */ unsigned char unknown_016C[0x4]; /* 0170 */ UITreeNode* unknown_0170; /* 0174 */ UITVBitmapButton* expandButton; /* 0178 */ UITVBitmapButton* collapseButton; @@ -35,20 +40,23 @@ public: void Slot27(int x, int y) override; void Slot31(int x, int y) override; void Slot35(int value) override; + int SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) override; virtual void Slot53(); void HideNodes(std::list& nodes); + bool DeleteChildNodes(UITreeNode* node); + int RemoveChildNode(UITreeNode* parent, int id, bool keepButtons); void AddNodeButtons(UITreeNode* node, int id); void AddNodeLabel(UITreeNode* node, int id); protected: /* 007C */ UIScrollBar* verticalBar; /* 0080 */ int verticalOverflow; - /* 0084 */ unsigned char unknown_0084[0x4]; - /* 0088 */ int unknown_0088; - /* 008C */ int unknown_008C; - /* 0090 */ int unknown_0090; - /* 0094 */ unsigned char unknown_0094[0x4]; + /* 0084 */ UITreeNode* root; + /* 0088 */ UITreeNode* unknown_0088; + /* 008C */ UITreeNode* unknown_008C; + /* 0090 */ UITreeNode* unknown_0090; + /* 0094 */ UITreeNode* editNode; /* 0098 */ UIEditCtrl2* edit; /* 009C */ int itemPadding; /* 00A0 */ int itemHeight;