#include <resolver>
-
Автор темы
- #1
Кто-нибудь может с этим помочь?
base:lw
base:lw
C++:
// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
#include <ShlObj_core.h>
#include <unordered_map>
#include "menu.h"
#include "../constchars.h"
#include "../cheats/misc/logs.h"
#include "tabs.h"
#include "byte.h"
#define ALPHA (ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_AlphaBar| ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_Float)
#define NOALPHA (ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_Float)
std::vector <std::string> files;
std::vector <std::string> scripts;
std::string editing_script;
auto selected_script = 0;
auto loaded_editing_script = false;
static auto menu_setupped = false;
static auto should_update = true;
IDirect3DTexture9* all_skins[36];
ImFont* iconfont = nullptr;
ImFont* themefont = nullptr;
ImFont* info = nullptr;
IDirect3DTexture9* logggo = nullptr;
ImFont* info_little = nullptr;
ImFont* two = nullptr;
ImFont* three = nullptr;
ImFont* tabsf = nullptr;
ImFont* ee = nullptr;
ImDrawList* draw;
static int tabs = 3;
static int subtabs = 0;
static int lang = 0;
static int theme = 0;
static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
void decorations()
{
if (logggo == nullptr)
D3DXCreateTextureFromFileInMemoryEx(g_pd3dDevice, &logo, sizeof(logo), 462, 462, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &logggo);
const ImVec2 pos(ui::GetWindowPos().x + 6, ui::GetWindowPos().y + 6);
draw->AddRectFilled(pos, ImVec2(pos.x + 720, pos.y + 510), ImColor(21, 24, 29), 5);
draw->AddRect(ImVec2(pos.x + 3, pos.y + 2), ImVec2(pos.x + 717, pos.y + 507), ImColor(35, 35, 35), 5.f, 15, 1.5f);
draw->AddLine(ImVec2(pos.x + 145, pos.y + 2), ImVec2(pos.x + 145, pos.y + 507), ImColor(35, 35, 35));
draw->AddLine(ImVec2(pos.x + 15, pos.y + 60), ImVec2(pos.x + 130, pos.y + 60), ImColor(35, 35, 35));
draw->AddCircleFilled(ImVec2(pos.x + 30, pos.y + 10), 4, ImColor(250, 91, 75), 360);
draw->AddCircleFilled(ImVec2(pos.x + 41, pos.y + 10), 4, ImColor(255, 191, 56), 360);
draw->AddCircleFilled(ImVec2(pos.x + 52, pos.y + 10), 4, ImColor(108, 240, 83), 360);
draw->AddCircleImageFilled(logggo, ImVec2(pos.x + 33, pos.y + 40), 12, ImColor(255, 255, 255), 360);
draw->AddText(ImVec2(pos.x + 56, pos.y + 33), ImColor(255, 255, 255), "Cheat.");
draw->AddText(ImVec2(pos.x + 93, pos.y + 33), ImColor(0, 150, 255), "name");
draw->AddLine(ImVec2(pos.x + 25, pos.y + 300), ImVec2(pos.x + 120, pos.y + 300), ImColor(35, 35, 35));
draw->AddText(ImVec2(pos.x + 25, pos.y + 415), ImColor(88, 88, 88), "Your account");
draw->AddLine(ImVec2(pos.x + 25, pos.y + 435), ImVec2(pos.x + 120, pos.y + 435), ImColor(35, 35, 35));
draw->AddCircleFilled(ImVec2(pos.x + 25, pos.y + 470), 12, ImColor(255, 255, 255), 360);
draw->AddText(ImVec2(pos.x + 45, pos.y + 455), ImColor(255, 255, 255), "monyfolity");
draw->AddText(ImVec2(pos.x + 45, pos.y + 470), ImColor(88, 88, 88), "Supporter");
static char search[64] = { 0 };
ui::SetCursorPos(ImVec2(175, 30));
draw->AddLine(ImVec2(pos.x + 504, pos.y + 33), ImVec2(pos.x + 504, pos.y + 52), ImColor(35, 35, 35), 1.f);
draw->AddRect(ImVec2(pos.x + 513, pos.y + 24), ImVec2(pos.x + 594, pos.y + 59), ImColor(35, 35, 35), 9);
draw->AddLine(ImVec2(pos.x + 553, pos.y + 33), ImVec2(pos.x + 553, pos.y + 52), ImColor(35, 35, 35), 1.f);
draw->AddLine(ImVec2(pos.x + 602, pos.y + 33), ImVec2(pos.x + 602, pos.y + 52), ImColor(35, 35, 35), 1.f);
draw->AddRect(ImVec2(pos.x + 611, pos.y + 24), ImVec2(pos.x + 691, pos.y + 59), ImColor(35, 35, 35), 9);
draw->AddLine(ImVec2(pos.x + 651, pos.y + 33), ImVec2(pos.x + 651, pos.y + 52), ImColor(35, 35, 35), 1.f);
ui::SetCursorPos(ImVec2(523, 30));
ui::BeginGroup();
{
if (ui::da("RUS", info, 0 == lang))
lang = 0;
ui::SameLine();
if (ui::da("ENG", info, 1 == lang))
lang = 1;
}
ui::EndGroup();
ui::SetCursorPos(ImVec2(622, 30));
ui::BeginGroup();
{
if (ui::da("A", themefont, 0 == theme))
theme = 0;
ui::SameLine(0, 1);
if (ui::da("B", themefont, 1 == theme))
theme = 1;
}
ui::EndGroup();
}
void tabs_()
{
ui::PushFont(info);
ui::SetCursorPos(ImVec2(22, 80));
ui::BeginGroup();
if (ui::tab("Ragebot", "A", "2", 0 == tabs))
tabs = 0;
if (ui::tab("Legitbot", "B", "2", 1 == tabs))
tabs = 1;
if (ui::tab("Visuals", "C", "3", 2 == tabs))
tabs = 2;
if (ui::tab("Skins", "G", "0", 3 == tabs))
tabs = 3;
if (ui::tab("Misc", "D", "0", 4 == tabs))
tabs = 4;
if (ui::tab("Configs", "E", "0", 5 == tabs))
tabs = 5;
if (ui::tab("Scripts", "F", "0", 6 == tabs))
tabs = 6;
ui::EndGroup();
ui::PopFont();
}
void subtabs_()
{
if (tabs == 0)
{
ui::SetCursorPos(ImVec2(22, 310));
ui::BeginGroup();
{
if (ui::sub("General", 3 == subtabs))
subtabs = 3;
if (ui::sub("Weapons", 4 == subtabs))
subtabs = 4;
}
ui::EndGroup();
}
if (tabs == 1)
{
ui::SetCursorPos(ImVec2(22, 310));
ui::BeginGroup();
{
if (ui::sub("General", 5 == subtabs))
subtabs = 5;
if (ui::sub("Weapons", 6 == subtabs))
subtabs = 6;
}
ui::EndGroup();
}
if (tabs == 2)
{
ui::SetCursorPos(ImVec2(22, 310));
ui::BeginGroup();
{
if (ui::sub("Enemy", 0 == subtabs))
subtabs = 0;
if (ui::sub("Team", 1 == subtabs))
subtabs = 1;
if (ui::sub("Local", 2 == subtabs))
subtabs = 2;
}
ui::EndGroup();
}
}
void function()
{
static bool da = false;
static int sliderint = 4;
static int combo = 0;
if (tabs == 2)
{
if (subtabs == 0)
{
ui::SetCursorPos(ImVec2(175, 85));
ui::BeginGroup();
ui::BeginChild("ESP", ImVec2(360, 200));
{
ui::SetCursorPos(ImVec2(20, 50));
ui::BeginGroup();
ui::Checkbox("Enabled", &da);
ui::SliderInt("SliderInt", &sliderint, 0, 100);
ui::EndGroup();
}
ui::EndChild();
ui::SameLine(0, 10);
ui::BeginChild("Glow", ImVec2(155, 200));
{
}
ui::EndChild();
ui::BeginChild("Chams", ImVec2(525, 200));
{
}
ui::EndChild();
ui::EndGroup();
}
}
}
std::string get_wep(int id, int custom_index = -1, bool knife = true)
{
if (custom_index > -1)
{
if (knife)
{
switch (custom_index)
{
case 0: return crypt_str("weapon_knife");
case 1: return crypt_str("weapon_bayonet");
case 2: return crypt_str("weapon_knife_css");
case 3: return crypt_str("weapon_knife_skeleton");
case 4: return crypt_str("weapon_knife_outdoor");
case 5: return crypt_str("weapon_knife_cord");
case 6: return crypt_str("weapon_knife_canis");
case 7: return crypt_str("weapon_knife_flip");
case 8: return crypt_str("weapon_knife_gut");
case 9: return crypt_str("weapon_knife_karambit");
case 10: return crypt_str("weapon_knife_m9_bayonet");
case 11: return crypt_str("weapon_knife_tactical");
case 12: return crypt_str("weapon_knife_falchion");
case 13: return crypt_str("weapon_knife_survival_bowie");
case 14: return crypt_str("weapon_knife_butterfly");
case 15: return crypt_str("weapon_knife_push");
case 16: return crypt_str("weapon_knife_ursus");
case 17: return crypt_str("weapon_knife_gypsy_jackknife");
case 18: return crypt_str("weapon_knife_stiletto");
case 19: return crypt_str("weapon_knife_widowmaker");
}
}
else
{
switch (custom_index)
{
case 0: return crypt_str("ct_gloves"); //-V1037
case 1: return crypt_str("studded_bloodhound_gloves");
case 2: return crypt_str("t_gloves");
case 3: return crypt_str("ct_gloves");
case 4: return crypt_str("sporty_gloves");
case 5: return crypt_str("slick_gloves");
case 6: return crypt_str("leather_handwraps");
case 7: return crypt_str("motorcycle_gloves");
case 8: return crypt_str("specialist_gloves");
case 9: return crypt_str("studded_hydra_gloves");
}
}
}
else
{
switch (id)
{
case 0: return crypt_str("knife");
case 1: return crypt_str("gloves");
case 2: return crypt_str("weapon_ak47");
case 3: return crypt_str("weapon_aug");
case 4: return crypt_str("weapon_awp");
case 5: return crypt_str("weapon_cz75a");
case 6: return crypt_str("weapon_deagle");
case 7: return crypt_str("weapon_elite");
case 8: return crypt_str("weapon_famas");
case 9: return crypt_str("weapon_fiveseven");
case 10: return crypt_str("weapon_g3sg1");
case 11: return crypt_str("weapon_galilar");
case 12: return crypt_str("weapon_glock");
case 13: return crypt_str("weapon_m249");
case 14: return crypt_str("weapon_m4a1_silencer");
case 15: return crypt_str("weapon_m4a1");
case 16: return crypt_str("weapon_mac10");
case 17: return crypt_str("weapon_mag7");
case 18: return crypt_str("weapon_mp5sd");
case 19: return crypt_str("weapon_mp7");
case 20: return crypt_str("weapon_mp9");
case 21: return crypt_str("weapon_negev");
case 22: return crypt_str("weapon_nova");
case 23: return crypt_str("weapon_hkp2000");
case 24: return crypt_str("weapon_p250");
case 25: return crypt_str("weapon_p90");
case 26: return crypt_str("weapon_bizon");
case 27: return crypt_str("weapon_revolver");
case 28: return crypt_str("weapon_sawedoff");
case 29: return crypt_str("weapon_scar20");
case 30: return crypt_str("weapon_ssg08");
case 31: return crypt_str("weapon_sg556");
case 32: return crypt_str("weapon_tec9");
case 33: return crypt_str("weapon_ump45");
case 34: return crypt_str("weapon_usp_silencer");
case 35: return crypt_str("weapon_xm1014");
default: return crypt_str("unknown");
}
}
}
IDirect3DTexture9* get_skin_preview(const char* weapon_name, const std::string& skin_name, IDirect3DDevice9* device)
{
IDirect3DTexture9* skin_image = nullptr;
std::string vpk_path;
if (strcmp(weapon_name, crypt_str("unknown")) && strcmp(weapon_name, crypt_str("knife")) && strcmp(weapon_name, crypt_str("gloves"))) //-V526
{
if (skin_name.empty() || skin_name == crypt_str("default"))
vpk_path = crypt_str("resource/flash/econ/weapons/base_weapons/") + std::string(weapon_name) + crypt_str(".png");
else
vpk_path = crypt_str("resource/flash/econ/default_generated/") + std::string(weapon_name) + crypt_str("_") + std::string(skin_name) + crypt_str("_light_large.png");
}
else
{
if (!strcmp(weapon_name, crypt_str("knife")))
vpk_path = crypt_str("resource/flash/econ/weapons/base_weapons/weapon_knife.png");
else if (!strcmp(weapon_name, crypt_str("gloves")))
vpk_path = crypt_str("resource/flash/econ/weapons/base_weapons/ct_gloves.png");
else if (!strcmp(weapon_name, crypt_str("unknown")))
vpk_path = crypt_str("resource/flash/econ/weapons/base_weapons/weapon_snowball.png");
}
const auto handle = m_basefilesys()->Open(vpk_path.c_str(), crypt_str("r"), crypt_str("GAME"));
if (handle)
{
int file_len = m_basefilesys()->Size(handle);
char* image = new char[file_len]; //-V121
m_basefilesys()->Read(image, file_len, handle);
m_basefilesys()->Close(handle);
D3DXCreateTextureFromFileInMemory(device, image, file_len, &skin_image);
delete[] image;
}
if (!skin_image)
{
std::string vpk_path;
if (strstr(weapon_name, crypt_str("bloodhound")) != NULL || strstr(weapon_name, crypt_str("hydra")) != NULL)
vpk_path = crypt_str("resource/flash/econ/weapons/base_weapons/ct_gloves.png");
else
vpk_path = crypt_str("resource/flash/econ/weapons/base_weapons/") + std::string(weapon_name) + crypt_str(".png");
const auto handle = m_basefilesys()->Open(vpk_path.c_str(), crypt_str("r"), crypt_str("GAME"));
if (handle)
{
int file_len = m_basefilesys()->Size(handle);
char* image = new char[file_len]; //-V121
m_basefilesys()->Read(image, file_len, handle);
m_basefilesys()->Close(handle);
D3DXCreateTextureFromFileInMemory(device, image, file_len, &skin_image);
delete[] image;
}
}
return skin_image;
}
// setup some styles and colors, window size and bg alpha
// dpi setup
void c_menu::menu_setup(ImGuiStyle& style) //-V688
{
ui::StyleColorsDark();
ui::SetNextWindowSize(ImVec2(width, height), ImGuiCond_Once); // window pos setup
//ui::SetNextWindowBgAlpha(min(style.Alpha, 0.94f)); // window bg alpha setup
style.ScrollbarSize = 0.0f;
// setup skins preview
for (auto i = 0; i < g_cfg.skins.skinChanger.size(); i++)
if (!all_skins[i])
all_skins[i] = get_skin_preview(get_wep(i, (i == 0 || i == 1) ? g_cfg.skins.skinChanger.at(i).definition_override_vector_index : -1, i == 0).c_str(), g_cfg.skins.skinChanger.at(i).skin_name, device); //-V810
menu_setupped = true; // we dont want to setup menu again
}
// resize current style sizes
void c_menu::dpi_resize(float scale_factor, ImGuiStyle& style) //-V688
{
}
std::string get_config_dir()
{
std::string folder;
static TCHAR path[MAX_PATH];
if (SUCCEEDED(SHGetFolderPath(NULL, 0x001a, NULL, NULL, path)))
folder = std::string(path) + crypt_str("\\Zenith.tech\\Configs\\");
CreateDirectory(folder.c_str(), NULL);
return folder;
}
void load_config()
{
if (cfg_manager->files.empty())
return;
cfg_manager->load(cfg_manager->files.at(g_cfg.selected_config), false);
c_lua::get().unload_all_scripts();
for (auto& script : g_cfg.scripts.scripts)
c_lua::get().load_script(c_lua::get().get_script_id(script));
scripts = c_lua::get().scripts;
if (selected_script >= scripts.size())
selected_script = scripts.size() - 1; //-V103
for (auto& current : scripts)
{
if (current.size() >= 5 && current.at(current.size() - 1) == 'c')
current.erase(current.size() - 5, 5);
else if (current.size() >= 4)
current.erase(current.size() - 4, 4);
}
for (auto i = 0; i < g_cfg.skins.skinChanger.size(); ++i)
all_skins[i] = nullptr;
g_cfg.scripts.scripts.clear();
cfg_manager->load(cfg_manager->files.at(g_cfg.selected_config), true);
cfg_manager->config_files();
eventlogs::get().addnew(crypt_str("Loaded ") + files.at(g_cfg.selected_config) + crypt_str(" config"), Color::Blue, false);
}
void save_config()
{
if (cfg_manager->files.empty())
return;
g_cfg.scripts.scripts.clear();
for (auto i = 0; i < c_lua::get().scripts.size(); ++i)
{
auto script = c_lua::get().scripts.at(i);
if (c_lua::get().loaded.at(i))
g_cfg.scripts.scripts.emplace_back(script);
}
cfg_manager->save(cfg_manager->files.at(g_cfg.selected_config));
cfg_manager->config_files();
eventlogs::get().addnew(crypt_str("Saved ") + files.at(g_cfg.selected_config) + crypt_str(" config"), Color::Blue, false);
}
void remove_config()
{
if (cfg_manager->files.empty())
return;
eventlogs::get().addnew(crypt_str("Removed ") + files.at(g_cfg.selected_config) + crypt_str(" config"), Color::Blue, false);
cfg_manager->remove(cfg_manager->files.at(g_cfg.selected_config));
cfg_manager->config_files();
files = cfg_manager->files;
if (g_cfg.selected_config >= files.size())
g_cfg.selected_config = files.size() - 1; //-V103
for (auto& current : files)
if (current.size() > 2)
current.erase(current.size() - 3, 3);
}
void add_config()
{
auto empty = true;
for (auto current : g_cfg.new_config_name)
{
if (current != ' ')
{
empty = false;
break;
}
}
if (empty)
g_cfg.new_config_name = crypt_str("config");
eventlogs::get().addnew(crypt_str("Added ") + g_cfg.new_config_name + crypt_str(" config"), Color::Blue, false);
if (g_cfg.new_config_name.find(crypt_str(".cfg")) == std::string::npos)
g_cfg.new_config_name += crypt_str(".cfg");
cfg_manager->save(g_cfg.new_config_name);
cfg_manager->config_files();
g_cfg.selected_config = cfg_manager->files.size() - 1; //-V103
files = cfg_manager->files;
for (auto& current : files)
if (current.size() > 2)
current.erase(current.size() - 3, 3);
}
__forceinline void padding(float x, float y)
{
//ui::SetCursorPosX(ui::GetCursorPosX() + x * c_menu::get().dpi_scale);
//ui::SetCursorPosY(ui::GetCursorPosY() + y * c_menu::get().dpi_scale);
}
// title of content child
void child_title(const char* label)
{
ui::PushFont(c_menu::get().futura_large);
ui::PushStyleColor(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 1.f));
ui::SetCursorPosX(ui::GetCursorPosX() + (12 * c_menu::get().dpi_scale));
ui::Text(label);
ui::PopStyleColor();
ui::PopFont();
}
void draw_combo(const char* name, int& variable, std::vector<const char*> f)
{
//ui::SetCursorPosX(ui::GetCursorPosX() - 6 * c_menu::get().dpi_scale);
//ui::Text(name);
//ui::SetCursorPosX(ui::GetCursorPosX() - 5 * c_menu::get().dpi_scale);
//ui::SingleSelect(std::string(crypt_str("##COMBO__") + std::string(name)).c_str(), &variable, f);
ui::SingleSelect(name, &variable, f);
}
void draw_multicombo(std::string name, std::vector<int>& variable, const char* labels[], int count, std::string& preview)
{
static auto howmuchsel = [](std::vector<int> e) -> int {
int s = 0;
for (int i = 0; i < e.size(); i++)
if (e[i])
s++;
return s;
};
if (ui::BeginCombo(name.c_str(), (howmuchsel(variable) > 0 ? std::to_string(howmuchsel(variable)) + " selected" : "None").c_str(), ImGuiComboFlags_HeightLarge, count)) // draw start
{
ui::BeginGroup();
{
for (auto i = 0; i < count; i++)
ui::Selectable(labels[i], (bool*)&variable[i], ImGuiSelectableFlags_DontClosePopups);
}
ui::EndGroup();
ui::EndCombo();
}
preview = crypt_str("None"); // reset preview to use later
}
bool LabelClick(const char* label, bool* v, const char* unique_id)
{
ImGuiWindow* window = ui::GetCurrentWindow();
if (window->SkipItems)
return false;
// The concatoff/on thingies were for my weapon config system so if we're going to make that, we still need this aids.
char Buf[64];
_snprintf(Buf, 62, crypt_str("%s"), label);
char getid[128];
sprintf_s(getid, 128, crypt_str("%s%s"), label, unique_id);
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(getid);
const ImVec2 label_size = ui::CalcTextSize(label, NULL, true);
const ImRect check_bb(window->DC.CursorPos, ImVec2(label_size.y + style.FramePadding.y * 2 + window->DC.CursorPos.x, window->DC.CursorPos.y + label_size.y + style.FramePadding.y * 2));
ui::ItemSize(check_bb, style.FramePadding.y);
ImRect total_bb = check_bb;
if (label_size.x > 0)
{
ui::SameLine(0, style.ItemInnerSpacing.x);
const ImRect text_bb(ImVec2(window->DC.CursorPos.x, window->DC.CursorPos.y + style.FramePadding.y), ImVec2(window->DC.CursorPos.x + label_size.x, window->DC.CursorPos.y + style.FramePadding.y + label_size.y));
ui::ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y);
total_bb = ImRect(ImMin(check_bb.Min, text_bb.Min), ImMax(check_bb.Max, text_bb.Max));
}
if (!ui::ItemAdd(total_bb, id))
return false;
bool hovered, held;
bool pressed = ui::ButtonBehavior(total_bb, id, &hovered, &held);
if (pressed)
*v = !(*v);
if (*v)
ui::PushStyleColor(ImGuiCol_Text, ImVec4(126 / 255.f, 131 / 255.f, 219 / 255.f, 1.f));
if (label_size.x > 0.0f)
ui::RenderText(ImVec2(check_bb.GetTL().x + 12, check_bb.GetTL().y), Buf);
if (*v)
ui::PopStyleColor();
return pressed;
}
static ImVec2 p;
void c_menu::draw(bool is_open)
{
static auto w = 0, h = 0, current_h = 0;
m_engine()->GetScreenSize(w, current_h);
if (h != current_h)
{
if (h)
update_scripts = true;
h = current_h;
update_dpi = true;
}
// animation related code
static float m_alpha = 0.0002f;
m_alpha = math::clamp(m_alpha + (3.f * ui::GetIO().DeltaTime * (is_open ? 1.f : -1.f)), 0.0001f, 1.f);
// set alpha in class to use later in widgets
public_alpha = m_alpha;
if (m_alpha <= 0.0001f)
return;
// set new alpha
ui::PushStyleVar(ImGuiStyleVar_Alpha, m_alpha);
// setup colors and some styles
if (!menu_setupped)
menu_setup(ui::GetStyle());
ui::PushStyleColor(ImGuiCol_ScrollbarGrab, ImVec4(ui::GetStyle().Colors[ImGuiCol_ScrollbarGrab].x, ui::GetStyle().Colors[ImGuiCol_ScrollbarGrab].y, ui::GetStyle().Colors[ImGuiCol_ScrollbarGrab].z, m_alpha));
// default menu size
const int x = 730, y = 480;
// last active tab to switch effect & reverse alpha & preview alpha
// IMPORTANT: DO TAB SWITCHING BY LAST_TAB!!!!!
static int last_tab = active_tab;
static bool preview_reverse = false;
// start menu render
ui::Begin("Menu", nullptr, ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_NoBringToFrontOnFocus);
{
static int x = 1000 * dpi_scale, y = 700 * dpi_scale;
ui::SetWindowSize(ImVec2(ImFloor(x * dpi_scale), ImFloor(y * dpi_scale)));
decorations();
tabs_();
subtabs_();
function();
}
ui::End();
ui::PopStyleColor();
ui::PopStyleVar();
}