diff --git a/Source/UI/SkillDelayInfo/UISkillDelayInfo.cpp b/Source/UI/SkillDelayInfo/UISkillDelayInfo.cpp index ee50c717..c6884b27 100644 --- a/Source/UI/SkillDelayInfo/UISkillDelayInfo.cpp +++ b/Source/UI/SkillDelayInfo/UISkillDelayInfo.cpp @@ -15,8 +15,18 @@ template <> void CUIListBoxEx::OnScroll(int position); // OFFSET: 0x00A71140 +// FUNCTION: fn_16799 +template <> +CUIListBoxEx::CUIListBoxEx(UIWindowContext& context) + : CUIControl(context), scrollBar(nullptr), itemWidth(0), rowHeight(0), itemX(0), itemY(0), unknown_00C4(0), selected(static_cast(-1)), + unknown_00E0(1), rebind(0) { +} // OFFSET: 0x00A71300 +// FUNCTION: fn_16800 +template <> +CUIListBoxEx::~CUIListBoxEx() { +} // OFFSET: 0x00A71950 // FUNCTION: fn_16806 @@ -43,6 +53,14 @@ void CUISkillDelayInfo::Slot53() { } // OFFSET: 0x00A71B50 +// FUNCTION: fn_16808 +template <> +void CUIListBoxEx::Slot15(int width, int height) { + this->scrollBar = new CUIVScrollBar(*this->m_context); + this->scrollBar->Show(0); + this->scrollBar->SetOnChange([this](int position) { this->OnScroll(position); }); + this->AddChild(this->scrollBar); +} // OFFSET: 0x00A75C80 // FUNCTION: fn_16812 @@ -52,8 +70,72 @@ void CUIListBoxEx: } // OFFSET: 0x00A75C90 +// FUNCTION: fn_16813 +template <> +void CUIListBoxEx::Slot35(int value) { + if (!this->scrollBar->dragging && this->scrollBar->total > this->scrollBar->visible) { + this->scrollBar->Slot35(value); + } else if (this->parent) { + this->parent->Slot35(value); + } +} // OFFSET: 0x00A76210 +// FUNCTION: fn_16817 +template <> +void CUIListBoxEx::OnScroll(int position) { + auto it = this->items.begin(); + if (it == this->items.end()) { + return; + } + if (this->data.size() == 0) { + for (; it != this->items.end(); ++it) { + (*it)->index = -1; + (*it)->Show(0); + } + return; + } + + const int first = (*it)->index; + unsigned int row = position / this->rowHeight; + if (first != -1) { + if (first < static_cast(row)) { + if (row - first < static_cast(this->items.size())) { + std::rotate(this->items.begin(), this->items.begin() + (row - first), this->items.end()); + } + } else if (first > static_cast(row)) { + if (first - row < static_cast(this->items.size())) { + std::rotate(this->items.begin(), this->items.end() - (first - row), this->items.end()); + } + } + } + + it = this->items.begin(); + for (int y = this->itemY - position % this->rowHeight; y < this->geometry.height; y += this->rowHeight, ++it, ++row) { + if (it == this->items.end() || row >= this->data.size()) { + break; + } + SkillDelayInfo::CUIDelayItem* item = *it; + if (item) { + if (this->rebind || row != static_cast(item->index)) { + item->index = row; + if (this->binder) { + auto node = this->data.begin(); + std::advance(node, static_cast(row)); + this->binder(item, *node); + } + } + item->SetSelected(row == this->selected); + item->Move(this->itemX, y); + item->Show(1); + } + } + + for (; it != this->items.end(); ++it) { + (*it)->index = -1; + (*it)->Show(0); + } +} namespace SkillDelayInfo { // OFFSET: 0x00A778C0