Decompile fn_11520 (UIItemTagOnChat::RemoveTagChild)
Batch #9684 by secret: 0 byte-identical, 1 confirmed by peer review. - fn_11520 UIItemTagOnChat::RemoveTagChild: logic confirmed by peer review Peer-reviewed-by: ragnarok-clanker, willerthal, superintelligence, KWDev Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
This commit is contained in:
parent
9fd4ebc9d5
commit
dcda289d48
4 changed files with 177 additions and 53 deletions
|
|
@ -1,3 +1,4 @@
|
|||
#include "Client/Input/Language.h"
|
||||
#include "Contents/Items/ItemInfo.h"
|
||||
#include "Contents/Items/ItemNaming.h"
|
||||
#include "UI/Buttons/UIItemTagButton.h"
|
||||
|
|
@ -26,21 +27,18 @@ struct ItemLinkOption {
|
|||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
// INLINED
|
||||
FocusedItemTagRemoval::FocusedItemTagRemoval(InputFocus& focus) : m_focus(focus) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x00896EB0
|
||||
// FUNCTION: fn_11519
|
||||
void FocusedItemTagRemoval::Remove(UIWindow* child) {
|
||||
if (this->m_focus.window) {
|
||||
this->m_focus.window->RemoveChild(child, 1);
|
||||
void UIItemTagCtrl::RemoveTagChild(UIWindow* child) {
|
||||
UIWindow* hoverWindow = g_windowMgr.GetHoverWindow();
|
||||
if (hoverWindow) {
|
||||
hoverWindow->RemoveChild(child, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00896EE0
|
||||
// FUNCTION: fn_11520
|
||||
void ChatItemTagRemoval::Remove(UIWindow* child) {
|
||||
void UIItemTagOnChat::RemoveTagChild(UIWindow* child) {
|
||||
if (g_inputSuggestionsEnabled == 1 && g_chatSuggestions->unknown_00BC != nullptr && g_chatSuggestions->unknown_00BC->Contains(child)) {
|
||||
g_chatSuggestions->unknown_00BC->RemoveChild(child, 1);
|
||||
return;
|
||||
|
|
@ -156,27 +154,19 @@ bool UIItemTagCtrl::SyncTagsWithText() {
|
|||
return true;
|
||||
}
|
||||
|
||||
// INLINED
|
||||
MailItemTagRemoval::MailItemTagRemoval(UIWindow* const& owner) : m_owner(owner) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x00896F60
|
||||
// FUNCTION: fn_11521
|
||||
void MailItemTagRemoval::Remove(UIWindow* child) {
|
||||
if (this->m_owner) {
|
||||
this->m_owner->RemoveChild(child, 1);
|
||||
void UIItemTagOnMail::RemoveTagChild(UIWindow* child) {
|
||||
if (g_windowMgr.unknown_0458) {
|
||||
g_windowMgr.unknown_0458->RemoveChild(child, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// INLINED
|
||||
MegaPhoneItemTagRemoval::MegaPhoneItemTagRemoval(UIWindow* const& owner) : m_owner(owner) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x00896F80
|
||||
// FUNCTION: fn_11522
|
||||
void MegaPhoneItemTagRemoval::Remove(UIWindow* child) {
|
||||
if (this->m_owner) {
|
||||
this->m_owner->RemoveChild(child, 1);
|
||||
void UIItemTagOnMegaPhone::RemoveTagChild(UIWindow* child) {
|
||||
if (g_windowMgr.unknown_0318) {
|
||||
g_windowMgr.unknown_0318->RemoveChild(child, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -344,3 +334,79 @@ bool UIItemTagOnMegaPhone::CanInsertTag(const std::string& name, int width) {
|
|||
std::string text = this->taggedText += tag;
|
||||
return text.size() <= maximum;
|
||||
}
|
||||
|
||||
// OFFSET: 0x008962C0
|
||||
void UIItemTagCtrl::sub_8962C0() {
|
||||
this->unknown_0140.clear();
|
||||
if (this->unknown_011C != static_cast<int>(this->tags.size()) && this->SyncTagsWithText()) {
|
||||
this->unknown_011C = static_cast<int>(this->tags.size());
|
||||
}
|
||||
|
||||
std::string prefix;
|
||||
std::string remaining = this->taggedText;
|
||||
if (!this->tags.empty()) {
|
||||
for (auto entry = this->tags.begin(); entry != this->tags.end();) {
|
||||
if (this->RemoveInvalidTag(entry)) {
|
||||
break;
|
||||
}
|
||||
|
||||
const std::string fitted = FitText(*this->geometry.surface, entry->name, this->tagWidth / 2);
|
||||
std::string display = "<";
|
||||
display += fitted;
|
||||
display += ">";
|
||||
|
||||
const std::size_t found = remaining.find(display);
|
||||
if (found != std::string::npos) {
|
||||
const std::string head = remaining.substr(0, found);
|
||||
prefix += head;
|
||||
|
||||
std::string visible = head;
|
||||
std::size_t firstVisible = 0;
|
||||
int x = 0;
|
||||
UIWindow* hover = g_windowMgr.GetHoverWindow();
|
||||
if (hover != nullptr) {
|
||||
switch (hover->geometry.id) {
|
||||
case 0x1EA:
|
||||
case 0x1EC:
|
||||
case 0x1ED:
|
||||
case 0x1EE:
|
||||
firstVisible = static_cast<UIEditCtrl*>(hover)->firstVisible;
|
||||
break;
|
||||
}
|
||||
|
||||
if (firstVisible <= prefix.size()) {
|
||||
visible = prefix.substr(firstVisible);
|
||||
}
|
||||
|
||||
if (firstVisible != 0 && prefix.size() <= firstVisible) {
|
||||
x = 1000;
|
||||
}
|
||||
}
|
||||
|
||||
this->PlaceTagButton(entry->child, visible, x, 0);
|
||||
|
||||
const int bytes = static_cast<int>(std::strlen(fitted.c_str()));
|
||||
if (!g_windowMgr.unknown_0458 || static_cast<UIRodexComposeWnd*>(g_windowMgr.unknown_0458)->m_contents == g_windowMgr.GetHoverWindow()) {
|
||||
const int cursor = this->m_edit->input.cursor;
|
||||
const int start = static_cast<int>(prefix.size());
|
||||
const int end = start + bytes + 2;
|
||||
if (cursor > start && cursor < end) {
|
||||
const int target = start + bytes / 2 + 1 > cursor ? end : start;
|
||||
this->m_edit->input.Select(target, target);
|
||||
}
|
||||
}
|
||||
|
||||
this->unknown_0140 += head;
|
||||
this->unknown_0140 += itemLinkTagOpening;
|
||||
this->unknown_0140 += entry->link;
|
||||
this->unknown_0140 += itemLinkTagClosing;
|
||||
remaining = remaining.substr(found + display.size());
|
||||
prefix += display;
|
||||
}
|
||||
|
||||
++entry;
|
||||
}
|
||||
}
|
||||
|
||||
this->unknown_0140 += remaining;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,34 +24,6 @@ protected:
|
|||
~ItemTagRemoval() = default;
|
||||
};
|
||||
|
||||
struct FocusedItemTagRemoval final : ItemTagRemoval {
|
||||
explicit FocusedItemTagRemoval(InputFocus& focus);
|
||||
void Remove(UIWindow* child) override;
|
||||
|
||||
private:
|
||||
InputFocus& m_focus;
|
||||
};
|
||||
|
||||
struct ChatItemTagRemoval final : ItemTagRemoval {
|
||||
void Remove(UIWindow* child) override;
|
||||
};
|
||||
|
||||
struct MailItemTagRemoval final : ItemTagRemoval {
|
||||
explicit MailItemTagRemoval(UIWindow* const& owner);
|
||||
void Remove(UIWindow* child) override;
|
||||
|
||||
private:
|
||||
UIWindow* const& m_owner;
|
||||
};
|
||||
|
||||
struct MegaPhoneItemTagRemoval final : ItemTagRemoval {
|
||||
explicit MegaPhoneItemTagRemoval(UIWindow* const& owner);
|
||||
void Remove(UIWindow* child) override;
|
||||
|
||||
private:
|
||||
UIWindow* const& m_owner;
|
||||
};
|
||||
|
||||
struct ItemTagRetirement {
|
||||
std::list<ItemTagRecord>& records;
|
||||
ItemTagRemoval& removal;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "UI/Edit/ItemTagRetirement.h"
|
||||
#include "UI/Edit/UIEditCtrl.h"
|
||||
#include "UI/TextTags.h"
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
|
@ -16,10 +17,13 @@ public:
|
|||
~UIItemTagCtrl() override;
|
||||
virtual bool CanInsertTag(const std::string& name, int width);
|
||||
virtual void AddTagButton(UIWindow* button);
|
||||
virtual void RemoveTagChild(UIWindow* child);
|
||||
virtual void PlaceTagButton(UIWindow* button, const std::string& name, const int& x, int unused) = 0;
|
||||
|
||||
std::string AppendTag(const std::string& name);
|
||||
int MeasureText(const std::string& text, const unsigned& bytes);
|
||||
bool SyncTagsWithText();
|
||||
bool RemoveInvalidTag(std::list<ItemTagRecord>::iterator& entry);
|
||||
void SetTaggedText(const std::string& text, int width);
|
||||
void sub_8962C0();
|
||||
void sub_89CFE0(const ITEM_INFO& item, unsigned int color);
|
||||
|
|
@ -36,7 +40,8 @@ class UIItemTagOnChat : public UIItemTagCtrl {
|
|||
public:
|
||||
UIItemTagOnChat();
|
||||
bool CanInsertTag(const std::string& name, int width) override;
|
||||
void PlaceTagButton(UIWindow* button, const std::string& name, const int& x, int unused);
|
||||
void RemoveTagChild(UIWindow* child) override;
|
||||
void PlaceTagButton(UIWindow* button, const std::string& name, const int& x, int unused) override;
|
||||
};
|
||||
|
||||
class UIItemTagOnMail : public UIItemTagCtrl {
|
||||
|
|
@ -45,7 +50,8 @@ public:
|
|||
bool CanInsertTag(const std::string& name, int width) override;
|
||||
void AddTagButton(UIWindow* button) override;
|
||||
void SetLines(const std::vector<std::string>& lines);
|
||||
void PlaceTagButton(UIWindow* button, const std::string& name, const int& x, int unused);
|
||||
void RemoveTagChild(UIWindow* child) override;
|
||||
void PlaceTagButton(UIWindow* button, const std::string& name, const int& x, int unused) override;
|
||||
|
||||
/* 015C */ std::vector<std::string> m_lines;
|
||||
};
|
||||
|
|
@ -55,7 +61,8 @@ public:
|
|||
UIItemTagOnMegaPhone();
|
||||
bool CanInsertTag(const std::string& name, int width) override;
|
||||
void AddTagButton(UIWindow* button) override;
|
||||
void PlaceTagButton(UIWindow* button, const std::string& name, const int& x, int unused);
|
||||
void RemoveTagChild(UIWindow* child) override;
|
||||
void PlaceTagButton(UIWindow* button, const std::string& name, const int& x, int unused) override;
|
||||
|
||||
/* 015C */ int textWidth;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@
|
|||
#include <cstdlib>
|
||||
#include <windows.h>
|
||||
#include <timeapi.h>
|
||||
#include "UI/Edit/UIItemTagCtrl.h"
|
||||
#include "UI/Rodex/UIRodexComposeWnd.h"
|
||||
#include "UI/Text/TextFitting.h"
|
||||
// OFFSET: 0x0086DDA0
|
||||
// FUNCTION: fn_11059
|
||||
UIListBoxTitle::UIListBoxTitle() : titleColor(0x92C0FA) {
|
||||
|
|
@ -1762,3 +1765,79 @@ void UITabControl::Configure(
|
|||
this->edit->Move(-100, -100);
|
||||
this->AddChild(this->edit);
|
||||
}
|
||||
|
||||
// OFFSET: 0x0087D240
|
||||
bool UIItemTagCtrl::RemoveInvalidTag(std::list<ItemTagRecord>::iterator& entry) {
|
||||
const std::string fitted = FitText(*this->geometry.surface, entry->name, this->tagWidth / 2);
|
||||
std::string remaining = this->taggedText;
|
||||
const int bytes = static_cast<int>(std::strlen(fitted.c_str()));
|
||||
int found = static_cast<int>(remaining.find(fitted));
|
||||
|
||||
if (found == -1) {
|
||||
this->RemoveTagChild(entry->child);
|
||||
entry = this->tags.erase(entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
int absolute = found;
|
||||
int count = 0;
|
||||
|
||||
do {
|
||||
std::string before;
|
||||
if (found > 0) {
|
||||
before = remaining.substr(found - 1, 1);
|
||||
}
|
||||
|
||||
std::string after;
|
||||
if (found + bytes >= 0) {
|
||||
after = remaining.substr(found + bytes, 1);
|
||||
}
|
||||
|
||||
bool atCursor;
|
||||
if (before.find("<") != std::string::npos && after.find(">") == std::string::npos) {
|
||||
atCursor = (!g_windowMgr.unknown_0458 || static_cast<UIRodexComposeWnd*>(g_windowMgr.unknown_0458)->m_contents == g_windowMgr.GetHoverWindow()) &&
|
||||
absolute + bytes == this->m_edit->input.cursor;
|
||||
} else if (before.find("<") == std::string::npos && after.find(">") != std::string::npos) {
|
||||
atCursor = (!g_windowMgr.unknown_0458 || static_cast<UIRodexComposeWnd*>(g_windowMgr.unknown_0458)->m_contents == g_windowMgr.GetHoverWindow()) &&
|
||||
absolute == this->m_edit->input.cursor;
|
||||
} else if (before.find("<") != std::string::npos && after.find(">") != std::string::npos) {
|
||||
++count;
|
||||
if (count > entry->index) {
|
||||
return false;
|
||||
}
|
||||
atCursor = false;
|
||||
} else {
|
||||
remaining = remaining.substr(found + bytes);
|
||||
absolute = (absolute == found ? absolute : absolute + found) + bytes;
|
||||
found = static_cast<int>(remaining.find(fitted));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (atCursor) {
|
||||
remaining = before.find("<") != std::string::npos ? this->taggedText.substr(0, absolute - 1) : this->taggedText.substr(0, absolute);
|
||||
int end = absolute;
|
||||
if (after.find(">") != std::string::npos) {
|
||||
++end;
|
||||
}
|
||||
remaining += this->taggedText.substr(end + bytes);
|
||||
this->m_edit->input.ResetInput();
|
||||
this->m_edit->input.Insert(remaining.c_str());
|
||||
this->RemoveTagChild(entry->child);
|
||||
entry = this->tags.erase(entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (entry->index == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
remaining = remaining.substr(found + bytes);
|
||||
found = static_cast<int>(remaining.find(fitted));
|
||||
if (found == -1) {
|
||||
return false;
|
||||
}
|
||||
absolute += found + bytes;
|
||||
} while (found != -1);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue