Add clipping support to DataList

This commit is contained in:
Grinch_ 2022-09-18 01:30:36 +06:00
parent c50152c38c
commit 27aac2411d
4 changed files with 130 additions and 95 deletions

View File

@ -16,6 +16,7 @@ ResourceStore::ResourceStore(const char* text, eResourceType type, ImVec2 imageS
{ {
m_Categories.push_back(std::string(k.str())); m_Categories.push_back(std::string(k.str()));
} }
UpdateSearchList();
} }
} }
@ -28,13 +29,9 @@ ResourceStore::ResourceStore(const char* text, eResourceType type, ImVec2 imageS
Maybe enabling a dx9 flag fixes this? Maybe enabling a dx9 flag fixes this?
Switch to initScriptsEvent Switch to initScriptsEvent
*/ */
Events::processScriptsEvent += [text, this]() Events::initGameEvent += [text, this]()
{ {
if (!m_bTexturesLoaded) LoadTextureResource(text);
{
LoadTextureResource(text);
m_bTexturesLoaded = true;
}
}; };
} }
} }
@ -147,4 +144,49 @@ void ResourceStore::LoadTextureResource(std::string&& name)
} }
while ( pEndDic != (RwTexDictionary*)&pRwTexDictionary->texturesInDict ); while ( pEndDic != (RwTexDictionary*)&pRwTexDictionary->texturesInDict );
} }
}
void ResourceStore::UpdateSearchList(bool favourites)
{
m_nSearchList.clear();
if (favourites)
{
for (auto [key, val] : *m_pData->GetTable("Favourites"))
{
std::string label = std::string(key.str());
if (m_Filter.PassFilter(label.c_str()))
{
std::string data = val.value_or<std::string>("Unkonwn");
m_nSearchList.push_back({std::move(std::string("Favourites")), std::move(label), std::move(data)});
}
}
}
else
{
for (auto [cat, table] : m_pData->Items())
{
// Don't show favourites in "All"
if (m_Selected == "All" && cat == "Favourites")
{
continue;
}
if (cat.str() == m_Selected || m_Selected == "All")
{
if (!table.as_table())
{
return;
}
for (auto [key, val] : *table.as_table()->as_table())
{
std::string label = std::string(key.str());
if (m_Filter.PassFilter(label.c_str()))
{
std::string data = val.value_or<std::string>("Unkonwn");
m_nSearchList.push_back({std::move(std::string(cat.str())), std::move(label), std::move(data)});
}
}
}
}
}
m_nSearchList.shrink_to_fit();
} }

View File

@ -52,6 +52,11 @@ enum eResourceType
class ResourceStore class ResourceStore
{ {
private: private:
struct SearchLookup
{
std::string cat, key, val;
};
// Loads a image texture from it's path // Loads a image texture from it's path
void LoadTextureResource(std::string&& path); void LoadTextureResource(std::string&& path);
@ -61,13 +66,14 @@ public:
std::string m_Selected = "All"; std::string m_Selected = "All";
std::string m_FileName; std::string m_FileName;
std::unique_ptr<DataStore> m_pData; std::unique_ptr<DataStore> m_pData;
std::vector<std::unique_ptr<TextureResource>> m_ImagesList; std::vector<SearchLookup> m_nSearchList;
ImVec2 m_ImageSize;
eResourceType m_Type; eResourceType m_Type;
bool m_bTexturesLoaded = false; ImVec2 m_ImageSize;
std::vector<std::unique_ptr<TextureResource>> m_ImagesList;
ResourceStore(const char* text, eResourceType type = TYPE_IMAGE, ImVec2 imageSize = ImVec2(64, 64)); ResourceStore(const char* text, eResourceType type = TYPE_IMAGE, ImVec2 imageSize = ImVec2(64, 64));
RwTexture* FindRwTextureByName(const std::string& name); RwTexture* FindRwTextureByName(const std::string& name);
IDirect3DTexture9** FindTextureByName(const std::string& name); IDirect3DTexture9** FindTextureByName(const std::string& name);
void UpdateSearchList(bool favourites = false);
}; };

View File

@ -59,10 +59,9 @@ void Widget::Tooltip(const char* text)
} }
} }
void Widget::Filter(const char* label, ImGuiTextFilter& filter, const char* hint) bool Widget::Filter(const char* label, ImGuiTextFilter& filter, const char* hint)
{ {
filter.Draw(label); bool state = filter.Draw(label);
if (strlen(filter.InputBuf) == 0) if (strlen(filter.InputBuf) == 0)
{ {
ImDrawList* drawlist = ImGui::GetWindowDrawList(); ImDrawList* drawlist = ImGui::GetWindowDrawList();
@ -73,6 +72,61 @@ void Widget::Filter(const char* label, ImGuiTextFilter& filter, const char* hint
drawlist->AddText(min, ImGui::GetColorU32(ImGuiCol_TextDisabled), hint); drawlist->AddText(min, ImGui::GetColorU32(ImGuiCol_TextDisabled), hint);
} }
return state;
}
void Widget::DrawClippedList(ResourceStore& data, fArg3_t clickFunc, bool favourites, bool isEditItem)
{
// Category box
ImGui::PushItemWidth(favourites ? ImGui::GetWindowContentRegionWidth() :
(ImGui::GetWindowContentRegionWidth() - ImGui::GetStyle().ItemSpacing.x)/2);
if (!favourites)
{
if (ListBox("##Categories", data.m_Categories, data.m_Selected))
{
data.UpdateSearchList(favourites);
}
ImGui::SameLine();
}
if (Filter("##Filter", data.m_Filter, TEXT("Window.Search")))
{
data.UpdateSearchList(favourites);
}
ImGui::PopItemWidth();
ImGui::Spacing();
ImGui::BeginChild(1);
ImGuiListClipper clipper(data.m_nSearchList.size(), ImGui::GetTextLineHeight());
while (clipper.Step())
{
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; ++i)
{
std::string &label = data.m_nSearchList[i].key;
std::string &cat = data.m_nSearchList[i].cat;
std::string &val = data.m_nSearchList[i].val;
if (isEditItem)
{
#ifdef GTASA
Widget::EditStat(label.c_str(), std::stoi(val));
#endif
}
else
{
if (ImGui::MenuItem(label.c_str()) && clickFunc != nullptr)
{
clickFunc(cat, label, val);
}
}
if (ImGui::IsItemClicked(1))
{
contextMenu = {cat, label, val, true};
}
}
}
} }
void Widget::DataList(ResourceStore& data, fArg3_t clickFunc, fArgNone_t addFunc, bool isEditItem) void Widget::DataList(ResourceStore& data, fArg3_t clickFunc, fArgNone_t addFunc, bool isEditItem)
@ -88,55 +142,7 @@ void Widget::DataList(ResourceStore& data, fArg3_t clickFunc, fArgNone_t addFunc
if (ImGui::BeginTabItem(TEXT("Window.Search"))) if (ImGui::BeginTabItem(TEXT("Window.Search")))
{ {
ImGui::Spacing(); ImGui::Spacing();
// Category box DrawClippedList(data, clickFunc, false, isEditItem);
ImGui::PushItemWidth((ImGui::GetWindowContentRegionWidth() - ImGui::GetStyle().ItemSpacing.x)/2);
Widget::ListBox("##Categories", data.m_Categories, data.m_Selected);
ImGui::SameLine();
Filter("##Filter", data.m_Filter, TEXT("Window.Search"));
ImGui::PopItemWidth();
ImGui::Spacing();
ImGui::BeginChild(1);
for (auto [k, v] : data.m_pData->Items())
{
// Don't show favourites in "All"
if (data.m_Selected == "All" && k == "Favourites")
{
continue;
}
if (k.str() == data.m_Selected || data.m_Selected == "All")
{
for (auto [k2, v2] : v.as_table()->ref<DataStore::Table>())
{
std::string key = std::string(k2.str());
if (data.m_Filter.PassFilter(key.c_str()))
{
std::string root = std::string(k.str());
std::string val = v2.value_or<std::string>("Unkonwn");
if (isEditItem)
{
#ifdef GTASA
Widget::EditStat(key.c_str(), std::stoi(val));
#endif
}
else
{
if (ImGui::MenuItem(key.c_str()) && clickFunc != nullptr)
{
clickFunc(root, key, val);
}
}
if (ImGui::IsItemClicked(1))
{
contextMenu = {root, key, val, true};
}
}
}
}
}
if (contextMenu.show) if (contextMenu.show)
{ {
if (ImGui::BeginPopupContextWindow()) if (ImGui::BeginPopupContextWindow())
@ -156,6 +162,7 @@ void Widget::DataList(ResourceStore& data, fArg3_t clickFunc, fArgNone_t addFunc
data.m_pData->RemoveKey("Custom", contextMenu.key.c_str()); data.m_pData->RemoveKey("Custom", contextMenu.key.c_str());
data.m_pData->RemoveKey("Favourites", contextMenu.key.c_str()); data.m_pData->RemoveKey("Favourites", contextMenu.key.c_str());
data.m_pData->Save(); data.m_pData->Save();
data.UpdateSearchList();
Util::SetMessage(TEXT("Window.RemoveEntry")); Util::SetMessage(TEXT("Window.RemoveEntry"));
} }
else else
@ -174,42 +181,14 @@ void Widget::DataList(ResourceStore& data, fArg3_t clickFunc, fArgNone_t addFunc
ImGui::EndChild(); ImGui::EndChild();
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (ImGui::IsItemClicked(ImGuiMouseButton_Left))
{
data.UpdateSearchList();
}
if (ImGui::BeginTabItem(TEXT("Window.FavouritesTab"))) if (ImGui::BeginTabItem(TEXT("Window.FavouritesTab")))
{ {
ImGui::Spacing(); ImGui::Spacing();
ImGui::PushItemWidth(ImGui::GetWindowContentRegionWidth()); DrawClippedList(data, clickFunc, true, isEditItem);
Filter("##Filter", data.m_Filter, TEXT("Window.Search"));
ImGui::PopItemWidth();
ImGui::Spacing();
ImGui::BeginChild(1);
for (auto [k, v] : *data.m_pData->GetTable("Favourites"))
{
std::string key = std::string(k.str());
if (data.m_Filter.PassFilter(key.c_str()))
{
std::string val = v.value_or<std::string>("Unkonwn");
if (isEditItem)
{
#ifdef GTASA
Widget::EditStat(key.c_str(), std::stoi(val));
#endif
}
else
{
if (ImGui::MenuItem(key.c_str()) && clickFunc != nullptr)
{
std::string str = "Favourites";
clickFunc(str, key, val);
}
}
if (ImGui::IsItemClicked(1))
{
contextMenu = {std::string("Favourites"), key, val, true};
}
}
}
if (data.m_pData->GetTable("Favourites")->size() == 0) if (data.m_pData->GetTable("Favourites")->size() == 0)
{ {
Widget::TextCentered(TEXT("Menu.FavouritesNone")); Widget::TextCentered(TEXT("Menu.FavouritesNone"));
@ -224,6 +203,7 @@ void Widget::DataList(ResourceStore& data, fArg3_t clickFunc, fArgNone_t addFunc
{ {
data.m_pData->RemoveKey("Favourites", contextMenu.key.c_str()); data.m_pData->RemoveKey("Favourites", contextMenu.key.c_str());
data.m_pData->Save(); data.m_pData->Save();
data.UpdateSearchList(true);
Util::SetMessage(TEXT("Menu.FavouritesRemoveText")); Util::SetMessage(TEXT("Menu.FavouritesRemoveText"));
} }
if (ImGui::MenuItem(TEXT("Menu.Close"))) if (ImGui::MenuItem(TEXT("Menu.Close")))
@ -237,6 +217,10 @@ void Widget::DataList(ResourceStore& data, fArg3_t clickFunc, fArgNone_t addFunc
ImGui::EndChild(); ImGui::EndChild();
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (ImGui::IsItemClicked(ImGuiMouseButton_Left))
{
data.UpdateSearchList(true);
}
if (addFunc) if (addFunc)
{ {
if (ImGui::BeginTabItem(TEXT("Window.AddNew"))) if (ImGui::BeginTabItem(TEXT("Window.AddNew")))

View File

@ -43,6 +43,9 @@ public:
// Draws DataStore data in the interface // Draws DataStore data in the interface
static void DataList(ResourceStore& data, fArg3_t clickFunc = nullptr, fArgNone_t addFunc = nullptr, bool isEditItem = false); static void DataList(ResourceStore& data, fArg3_t clickFunc = nullptr, fArgNone_t addFunc = nullptr, bool isEditItem = false);
// Draws listed data, used in DataList
static void DrawClippedList(ResourceStore& data, fArg3_t clickFunc = nullptr, bool favourites = false, bool isEditItem = false);
// Draws a dropdown editor for memory address // Draws a dropdown editor for memory address
template <typename T> template <typename T>
static void EditAddr(const char* label, uint address, int min = 0, int def = 0, int max = 100); static void EditAddr(const char* label, uint address, int min = 0, int def = 0, int max = 100);
@ -62,7 +65,7 @@ public:
#endif #endif
// ImGui::TextFilter with hint support // ImGui::TextFilter with hint support
static void Filter(const char* label, ImGuiTextFilter& filter, const char* hint); static bool Filter(const char* label, ImGuiTextFilter& filter, const char* hint);
// Input widgets with increment & decrement buttons // Input widgets with increment & decrement buttons
static bool InputFloat(const char* label, float *val, float change = 1.0f, float min = -1.0f, float max = -1.0f); static bool InputFloat(const char* label, float *val, float change = 1.0f, float min = -1.0f, float max = -1.0f);