Add clipping support to DataList
This commit is contained in:
parent
c50152c38c
commit
27aac2411d
@ -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();
|
||||||
}
|
}
|
@ -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);
|
||||||
};
|
};
|
@ -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")))
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user