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()));
|
||||
}
|
||||
UpdateSearchList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,13 +29,9 @@ ResourceStore::ResourceStore(const char* text, eResourceType type, ImVec2 imageS
|
||||
Maybe enabling a dx9 flag fixes this?
|
||||
Switch to initScriptsEvent
|
||||
*/
|
||||
Events::processScriptsEvent += [text, this]()
|
||||
Events::initGameEvent += [text, this]()
|
||||
{
|
||||
if (!m_bTexturesLoaded)
|
||||
{
|
||||
LoadTextureResource(text);
|
||||
m_bTexturesLoaded = true;
|
||||
}
|
||||
LoadTextureResource(text);
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -147,4 +144,49 @@ void ResourceStore::LoadTextureResource(std::string&& name)
|
||||
}
|
||||
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
|
||||
{
|
||||
private:
|
||||
struct SearchLookup
|
||||
{
|
||||
std::string cat, key, val;
|
||||
};
|
||||
|
||||
// Loads a image texture from it's path
|
||||
void LoadTextureResource(std::string&& path);
|
||||
|
||||
@ -61,13 +66,14 @@ public:
|
||||
std::string m_Selected = "All";
|
||||
std::string m_FileName;
|
||||
std::unique_ptr<DataStore> m_pData;
|
||||
std::vector<std::unique_ptr<TextureResource>> m_ImagesList;
|
||||
ImVec2 m_ImageSize;
|
||||
std::vector<SearchLookup> m_nSearchList;
|
||||
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));
|
||||
|
||||
RwTexture* FindRwTextureByName(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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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)
|
||||
@ -88,55 +142,7 @@ void Widget::DataList(ResourceStore& data, fArg3_t clickFunc, fArgNone_t addFunc
|
||||
if (ImGui::BeginTabItem(TEXT("Window.Search")))
|
||||
{
|
||||
ImGui::Spacing();
|
||||
// Category box
|
||||
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};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DrawClippedList(data, clickFunc, false, isEditItem);
|
||||
if (contextMenu.show)
|
||||
{
|
||||
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("Favourites", contextMenu.key.c_str());
|
||||
data.m_pData->Save();
|
||||
data.UpdateSearchList();
|
||||
Util::SetMessage(TEXT("Window.RemoveEntry"));
|
||||
}
|
||||
else
|
||||
@ -174,42 +181,14 @@ void Widget::DataList(ResourceStore& data, fArg3_t clickFunc, fArgNone_t addFunc
|
||||
ImGui::EndChild();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Left))
|
||||
{
|
||||
data.UpdateSearchList();
|
||||
}
|
||||
if (ImGui::BeginTabItem(TEXT("Window.FavouritesTab")))
|
||||
{
|
||||
ImGui::Spacing();
|
||||
ImGui::PushItemWidth(ImGui::GetWindowContentRegionWidth());
|
||||
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};
|
||||
}
|
||||
}
|
||||
}
|
||||
DrawClippedList(data, clickFunc, true, isEditItem);
|
||||
if (data.m_pData->GetTable("Favourites")->size() == 0)
|
||||
{
|
||||
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->Save();
|
||||
data.UpdateSearchList(true);
|
||||
Util::SetMessage(TEXT("Menu.FavouritesRemoveText"));
|
||||
}
|
||||
if (ImGui::MenuItem(TEXT("Menu.Close")))
|
||||
@ -237,6 +217,10 @@ void Widget::DataList(ResourceStore& data, fArg3_t clickFunc, fArgNone_t addFunc
|
||||
ImGui::EndChild();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Left))
|
||||
{
|
||||
data.UpdateSearchList(true);
|
||||
}
|
||||
if (addFunc)
|
||||
{
|
||||
if (ImGui::BeginTabItem(TEXT("Window.AddNew")))
|
||||
|
@ -43,6 +43,9 @@ public:
|
||||
// Draws DataStore data in the interface
|
||||
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
|
||||
template <typename T>
|
||||
static void EditAddr(const char* label, uint address, int min = 0, int def = 0, int max = 100);
|
||||
@ -62,7 +65,7 @@ public:
|
||||
#endif
|
||||
|
||||
// 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
|
||||
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