mirror of
https://github.com/Bloodysharp/Synthetic.git
synced 2026-10-10 11:33:10 +08:00
Interface Synthetic
This commit is contained in:
+20171
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,792 @@
|
||||
// dear imgui: FreeType font builder (used as a replacement for the stb_truetype builder)
|
||||
// (code)
|
||||
|
||||
// Get the latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
|
||||
// Original code by @vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained since 2019 by @ocornut.
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023/01/04: fixed a packing issue which in some occurrences would prevent large amount of glyphs from being packed correctly.
|
||||
// 2021/08/23: fixed crash when FT_Render_Glyph() fails to render a glyph and returns NULL.
|
||||
// 2021/03/05: added ImGuiFreeTypeBuilderFlags_Bitmap to load bitmap glyphs.
|
||||
// 2021/03/02: set 'atlas->TexPixelsUseColors = true' to help some backends with deciding of a prefered texture format.
|
||||
// 2021/01/28: added support for color-layered glyphs via ImGuiFreeTypeBuilderFlags_LoadColor (require Freetype 2.10+).
|
||||
// 2021/01/26: simplified integration by using '#define IMGUI_ENABLE_FREETYPE'.
|
||||
// renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API. removed ImGuiFreeType::BuildFontAtlas().
|
||||
// 2020/06/04: fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
|
||||
// 2019/02/09: added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!)
|
||||
// 2019/01/15: added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
|
||||
// 2019/01/10: re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding.
|
||||
// 2018/06/08: added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX.
|
||||
// 2018/02/04: moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club)
|
||||
// 2018/01/22: fix for addition of ImFontAtlas::TexUvscale member.
|
||||
// 2017/10/22: minor inconsequential change to match change in master (removed an unnecessary statement).
|
||||
// 2017/09/26: fixes for imgui internal changes.
|
||||
// 2017/08/26: cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply.
|
||||
// 2017/08/16: imported from https://github.com/Vuhdo/imgui_freetype into http://www.github.com/ocornut/imgui_club, updated for latest changes in ImFontAtlas, minor tweaks.
|
||||
|
||||
// About Gamma Correct Blending:
|
||||
// - FreeType assumes blending in linear space rather than gamma space.
|
||||
// - See https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph
|
||||
// - For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
|
||||
// - The default dear imgui styles will be impacted by this change (alpha values will need tweaking).
|
||||
|
||||
// FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
|
||||
|
||||
#include "../../framework/data/imgui_freetype.h"
|
||||
#include "imgui_internal.h" // ImMin,ImMax,ImFontAtlasBuild*,
|
||||
#include <stdint.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H // <freetype/freetype.h>
|
||||
#include FT_MODULE_H // <freetype/ftmodapi.h>
|
||||
#include FT_GLYPH_H // <freetype/ftglyph.h>
|
||||
#include FT_SYNTHESIS_H // <freetype/ftsynth.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff)
|
||||
#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
|
||||
#pragma GCC diagnostic ignored "-Wsubobject-linkage" // warning: 'xxxx' has a field ‘xxxx’ whose type uses the anonymous namespace
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Data
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Default memory allocators
|
||||
static void* ImGuiFreeTypeDefaultAllocFunc(size_t size, void* user_data) { IM_UNUSED(user_data); return IM_ALLOC(size); }
|
||||
static void ImGuiFreeTypeDefaultFreeFunc(void* ptr, void* user_data) { IM_UNUSED(user_data); IM_FREE(ptr); }
|
||||
|
||||
// Current memory allocators
|
||||
static void* (*GImGuiFreeTypeAllocFunc)(size_t size, void* user_data) = ImGuiFreeTypeDefaultAllocFunc;
|
||||
static void (*GImGuiFreeTypeFreeFunc)(void* ptr, void* user_data) = ImGuiFreeTypeDefaultFreeFunc;
|
||||
static void* GImGuiFreeTypeAllocatorUserData = NULL;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Code
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
namespace
|
||||
{
|
||||
// Glyph metrics:
|
||||
// --------------
|
||||
//
|
||||
// xmin xmax
|
||||
// | |
|
||||
// |<-------- width -------->|
|
||||
// | |
|
||||
// | +-------------------------+----------------- ymax
|
||||
// | | ggggggggg ggggg | ^ ^
|
||||
// | | g:::::::::ggg::::g | | |
|
||||
// | | g:::::::::::::::::g | | |
|
||||
// | | g::::::ggggg::::::gg | | |
|
||||
// | | g:::::g g:::::g | | |
|
||||
// offsetX -|-------->| g:::::g g:::::g | offsetY |
|
||||
// | | g:::::g g:::::g | | |
|
||||
// | | g::::::g g:::::g | | |
|
||||
// | | g:::::::ggggg:::::g | | |
|
||||
// | | g::::::::::::::::g | | height
|
||||
// | | gg::::::::::::::g | | |
|
||||
// baseline ---*---------|---- gggggggg::::::g-----*-------- |
|
||||
// / | | g:::::g | |
|
||||
// origin | | gggggg g:::::g | |
|
||||
// | | g:::::gg gg:::::g | |
|
||||
// | | g::::::ggg:::::::g | |
|
||||
// | | gg:::::::::::::g | |
|
||||
// | | ggg::::::ggg | |
|
||||
// | | gggggg | v
|
||||
// | +-------------------------+----------------- ymin
|
||||
// | |
|
||||
// |------------- advanceX ----------->|
|
||||
|
||||
// A structure that describe a glyph.
|
||||
struct GlyphInfo
|
||||
{
|
||||
int Width; // Glyph's width in pixels.
|
||||
int Height; // Glyph's height in pixels.
|
||||
FT_Int OffsetX; // The distance from the origin ("pen position") to the left of the glyph.
|
||||
FT_Int OffsetY; // The distance from the origin to the top of the glyph. This is usually a value < 0.
|
||||
float AdvanceX; // The distance from the origin to the origin of the next glyph. This is usually a value > 0.
|
||||
bool IsColored; // The glyph is colored
|
||||
};
|
||||
|
||||
// Font parameters and metrics.
|
||||
struct FontInfo
|
||||
{
|
||||
uint32_t PixelHeight; // Size this font was generated with.
|
||||
float Ascender; // The pixel extents above the baseline in pixels (typically positive).
|
||||
float Descender; // The extents below the baseline in pixels (typically negative).
|
||||
float LineSpacing; // The baseline-to-baseline distance. Note that it usually is larger than the sum of the ascender and descender taken as absolute values. There is also no guarantee that no glyphs extend above or below subsequent baselines when using this distance. Think of it as a value the designer of the font finds appropriate.
|
||||
float LineGap; // The spacing in pixels between one row's descent and the next row's ascent.
|
||||
float MaxAdvanceWidth; // This field gives the maximum horizontal cursor advance for all glyphs in the font.
|
||||
};
|
||||
|
||||
// FreeType glyph rasterizer.
|
||||
// NB: No ctor/dtor, explicitly call Init()/Shutdown()
|
||||
struct FreeTypeFont
|
||||
{
|
||||
bool InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags); // Initialize from an external data buffer. Doesn't copy data, and you must ensure it stays valid up to this object lifetime.
|
||||
void CloseFont();
|
||||
void SetPixelHeight(int pixel_height); // Change font pixel size. All following calls to RasterizeGlyph() will use this size
|
||||
const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint);
|
||||
const FT_Bitmap* RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info);
|
||||
void BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch, unsigned char* multiply_table = NULL);
|
||||
~FreeTypeFont() { CloseFont(); }
|
||||
|
||||
// [Internals]
|
||||
FontInfo Info; // Font descriptor of the current font.
|
||||
FT_Face Face;
|
||||
unsigned int UserFlags; // = ImFontConfig::RasterizerFlags
|
||||
FT_Int32 LoadFlags;
|
||||
FT_Render_Mode RenderMode;
|
||||
};
|
||||
|
||||
// From SDL_ttf: Handy routines for converting from fixed point
|
||||
#define FT_CEIL(X) (((X + 63) & -64) / 64)
|
||||
|
||||
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_font_builder_flags)
|
||||
{
|
||||
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
|
||||
if (error != 0)
|
||||
return false;
|
||||
error = FT_Select_Charmap(Face, FT_ENCODING_UNICODE);
|
||||
if (error != 0)
|
||||
return false;
|
||||
|
||||
// Convert to FreeType flags (NB: Bold and Oblique are processed separately)
|
||||
UserFlags = cfg.FontBuilderFlags | extra_font_builder_flags;
|
||||
|
||||
LoadFlags = 0;
|
||||
if ((UserFlags & ImGuiFreeTypeBuilderFlags_Bitmap) == 0)
|
||||
LoadFlags |= FT_LOAD_NO_BITMAP;
|
||||
|
||||
if (UserFlags & ImGuiFreeTypeBuilderFlags_NoHinting)
|
||||
LoadFlags |= FT_LOAD_NO_HINTING;
|
||||
if (UserFlags & ImGuiFreeTypeBuilderFlags_NoAutoHint)
|
||||
LoadFlags |= FT_LOAD_NO_AUTOHINT;
|
||||
if (UserFlags & ImGuiFreeTypeBuilderFlags_ForceAutoHint)
|
||||
LoadFlags |= FT_LOAD_FORCE_AUTOHINT;
|
||||
if (UserFlags & ImGuiFreeTypeBuilderFlags_LightHinting)
|
||||
LoadFlags |= FT_LOAD_TARGET_LIGHT;
|
||||
else if (UserFlags & ImGuiFreeTypeBuilderFlags_MonoHinting)
|
||||
LoadFlags |= FT_LOAD_TARGET_MONO;
|
||||
else
|
||||
LoadFlags |= FT_LOAD_TARGET_NORMAL;
|
||||
|
||||
if (UserFlags & ImGuiFreeTypeBuilderFlags_Monochrome)
|
||||
RenderMode = FT_RENDER_MODE_MONO;
|
||||
else
|
||||
RenderMode = FT_RENDER_MODE_NORMAL;
|
||||
|
||||
if (UserFlags & ImGuiFreeTypeBuilderFlags_LoadColor)
|
||||
LoadFlags |= FT_LOAD_COLOR;
|
||||
|
||||
memset(&Info, 0, sizeof(Info));
|
||||
SetPixelHeight((uint32_t)cfg.SizePixels);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FreeTypeFont::CloseFont()
|
||||
{
|
||||
if (Face)
|
||||
{
|
||||
FT_Done_Face(Face);
|
||||
Face = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void FreeTypeFont::SetPixelHeight(int pixel_height)
|
||||
{
|
||||
// Vuhdo: I'm not sure how to deal with font sizes properly. As far as I understand, currently ImGui assumes that the 'pixel_height'
|
||||
// is a maximum height of an any given glyph, i.e. it's the sum of font's ascender and descender. Seems strange to me.
|
||||
// NB: FT_Set_Pixel_Sizes() doesn't seem to get us the same result.
|
||||
FT_Size_RequestRec req;
|
||||
req.type = (UserFlags & ImGuiFreeTypeBuilderFlags_Bitmap) ? FT_SIZE_REQUEST_TYPE_NOMINAL : FT_SIZE_REQUEST_TYPE_REAL_DIM;
|
||||
req.width = 0;
|
||||
req.height = (uint32_t)pixel_height * 64;
|
||||
req.horiResolution = 0;
|
||||
req.vertResolution = 0;
|
||||
FT_Request_Size(Face, &req);
|
||||
|
||||
// Update font info
|
||||
FT_Size_Metrics metrics = Face->size->metrics;
|
||||
Info.PixelHeight = (uint32_t)pixel_height;
|
||||
Info.Ascender = (float)FT_CEIL(metrics.ascender);
|
||||
Info.Descender = (float)FT_CEIL(metrics.descender);
|
||||
Info.LineSpacing = (float)FT_CEIL(metrics.height);
|
||||
Info.LineGap = (float)FT_CEIL(metrics.height - metrics.ascender + metrics.descender);
|
||||
Info.MaxAdvanceWidth = (float)FT_CEIL(metrics.max_advance);
|
||||
}
|
||||
|
||||
const FT_Glyph_Metrics* FreeTypeFont::LoadGlyph(uint32_t codepoint)
|
||||
{
|
||||
uint32_t glyph_index = FT_Get_Char_Index(Face, codepoint);
|
||||
if (glyph_index == 0)
|
||||
return NULL;
|
||||
|
||||
// If this crash for you: FreeType 2.11.0 has a crash bug on some bitmap/colored fonts.
|
||||
// - https://gitlab.freedesktop.org/freetype/freetype/-/issues/1076
|
||||
// - https://github.com/ocornut/imgui/issues/4567
|
||||
// - https://github.com/ocornut/imgui/issues/4566
|
||||
// You can use FreeType 2.10, or the patched version of 2.11.0 in VcPkg, or probably any upcoming FreeType version.
|
||||
FT_Error error = FT_Load_Glyph(Face, glyph_index, LoadFlags);
|
||||
if (error)
|
||||
return NULL;
|
||||
|
||||
// Need an outline for this to work
|
||||
FT_GlyphSlot slot = Face->glyph;
|
||||
IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP);
|
||||
|
||||
// Apply convenience transform (this is not picking from real "Bold"/"Italic" fonts! Merely applying FreeType helper transform. Oblique == Slanting)
|
||||
if (UserFlags & ImGuiFreeTypeBuilderFlags_Bold)
|
||||
FT_GlyphSlot_Embolden(slot);
|
||||
if (UserFlags & ImGuiFreeTypeBuilderFlags_Oblique)
|
||||
{
|
||||
FT_GlyphSlot_Oblique(slot);
|
||||
//FT_BBox bbox;
|
||||
//FT_Outline_Get_BBox(&slot->outline, &bbox);
|
||||
//slot->metrics.width = bbox.xMax - bbox.xMin;
|
||||
//slot->metrics.height = bbox.yMax - bbox.yMin;
|
||||
}
|
||||
|
||||
return &slot->metrics;
|
||||
}
|
||||
|
||||
const FT_Bitmap* FreeTypeFont::RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info)
|
||||
{
|
||||
FT_GlyphSlot slot = Face->glyph;
|
||||
FT_Error error = FT_Render_Glyph(slot, RenderMode);
|
||||
if (error != 0)
|
||||
return NULL;
|
||||
|
||||
FT_Bitmap* ft_bitmap = &Face->glyph->bitmap;
|
||||
out_glyph_info->Width = (int)ft_bitmap->width;
|
||||
out_glyph_info->Height = (int)ft_bitmap->rows;
|
||||
out_glyph_info->OffsetX = Face->glyph->bitmap_left;
|
||||
out_glyph_info->OffsetY = -Face->glyph->bitmap_top;
|
||||
out_glyph_info->AdvanceX = (float)FT_CEIL(slot->advance.x);
|
||||
out_glyph_info->IsColored = (ft_bitmap->pixel_mode == FT_PIXEL_MODE_BGRA);
|
||||
|
||||
return ft_bitmap;
|
||||
}
|
||||
|
||||
void FreeTypeFont::BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch, unsigned char* multiply_table)
|
||||
{
|
||||
IM_ASSERT(ft_bitmap != NULL);
|
||||
const uint32_t w = ft_bitmap->width;
|
||||
const uint32_t h = ft_bitmap->rows;
|
||||
const uint8_t* src = ft_bitmap->buffer;
|
||||
const uint32_t src_pitch = ft_bitmap->pitch;
|
||||
|
||||
switch (ft_bitmap->pixel_mode)
|
||||
{
|
||||
case FT_PIXEL_MODE_GRAY: // Grayscale image, 1 byte per pixel.
|
||||
{
|
||||
if (multiply_table == NULL)
|
||||
{
|
||||
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
|
||||
for (uint32_t x = 0; x < w; x++)
|
||||
dst[x] = IM_COL32(255, 255, 255, src[x]);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
|
||||
for (uint32_t x = 0; x < w; x++)
|
||||
dst[x] = IM_COL32(255, 255, 255, multiply_table[src[x]]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FT_PIXEL_MODE_MONO: // Monochrome image, 1 bit per pixel. The bits in each byte are ordered from MSB to LSB.
|
||||
{
|
||||
uint8_t color0 = multiply_table ? multiply_table[0] : 0;
|
||||
uint8_t color1 = multiply_table ? multiply_table[255] : 255;
|
||||
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
|
||||
{
|
||||
uint8_t bits = 0;
|
||||
const uint8_t* bits_ptr = src;
|
||||
for (uint32_t x = 0; x < w; x++, bits <<= 1)
|
||||
{
|
||||
if ((x & 7) == 0)
|
||||
bits = *bits_ptr++;
|
||||
dst[x] = IM_COL32(255, 255, 255, (bits & 0x80) ? color1 : color0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FT_PIXEL_MODE_BGRA:
|
||||
{
|
||||
// FIXME: Converting pre-multiplied alpha to straight. Doesn't smell good.
|
||||
#define DE_MULTIPLY(color, alpha) (ImU32)(255.0f * (float)color / (float)alpha + 0.5f)
|
||||
if (multiply_table == NULL)
|
||||
{
|
||||
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
|
||||
for (uint32_t x = 0; x < w; x++)
|
||||
{
|
||||
uint8_t r = src[x * 4 + 2], g = src[x * 4 + 1], b = src[x * 4], a = src[x * 4 + 3];
|
||||
dst[x] = IM_COL32(DE_MULTIPLY(r, a), DE_MULTIPLY(g, a), DE_MULTIPLY(b, a), a);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
|
||||
{
|
||||
for (uint32_t x = 0; x < w; x++)
|
||||
{
|
||||
uint8_t r = src[x * 4 + 2], g = src[x * 4 + 1], b = src[x * 4], a = src[x * 4 + 3];
|
||||
dst[x] = IM_COL32(multiply_table[DE_MULTIPLY(r, a)], multiply_table[DE_MULTIPLY(g, a)], multiply_table[DE_MULTIPLY(b, a)], multiply_table[a]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef DE_MULTIPLY
|
||||
break;
|
||||
}
|
||||
default:
|
||||
IM_ASSERT(0 && "FreeTypeFont::BlitGlyph(): Unknown bitmap pixel mode!");
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
#ifndef STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
|
||||
#ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||
#define STBRP_ASSERT(x) do { IM_ASSERT(x); } while (0)
|
||||
#define STBRP_STATIC
|
||||
#define STB_RECT_PACK_IMPLEMENTATION
|
||||
#endif
|
||||
#ifdef IMGUI_STB_RECT_PACK_FILENAME
|
||||
#include IMGUI_STB_RECT_PACK_FILENAME
|
||||
#else
|
||||
#include "imstb_rectpack.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct ImFontBuildSrcGlyphFT
|
||||
{
|
||||
GlyphInfo Info;
|
||||
uint32_t Codepoint;
|
||||
unsigned int* BitmapData; // Point within one of the dst_tmp_bitmap_buffers[] array
|
||||
|
||||
ImFontBuildSrcGlyphFT() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
struct ImFontBuildSrcDataFT
|
||||
{
|
||||
FreeTypeFont Font;
|
||||
stbrp_rect* Rects; // Rectangle to pack. We first fill in their size and the packer will give us their position.
|
||||
const ImWchar* SrcRanges; // Ranges as requested by user (user is allowed to request too much, e.g. 0x0020..0xFFFF)
|
||||
int DstIndex; // Index into atlas->Fonts[] and dst_tmp_array[]
|
||||
int GlyphsHighest; // Highest requested codepoint
|
||||
int GlyphsCount; // Glyph count (excluding missing glyphs and glyphs already set by an earlier source font)
|
||||
ImBitVector GlyphsSet; // Glyph bit map (random access, 1-bit per codepoint. This will be a maximum of 8KB)
|
||||
ImVector<ImFontBuildSrcGlyphFT> GlyphsList;
|
||||
};
|
||||
|
||||
// Temporary data for one destination ImFont* (multiple source fonts can be merged into one destination ImFont)
|
||||
struct ImFontBuildDstDataFT
|
||||
{
|
||||
int SrcCount; // Number of source fonts targeting this destination font.
|
||||
int GlyphsHighest;
|
||||
int GlyphsCount;
|
||||
ImBitVector GlyphsSet; // This is used to resolve collision when multiple sources are merged into a same destination font.
|
||||
};
|
||||
|
||||
bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, unsigned int extra_flags)
|
||||
{
|
||||
IM_ASSERT(atlas->ConfigData.Size > 0);
|
||||
|
||||
ImFontAtlasBuildInit(atlas);
|
||||
|
||||
// Clear atlas
|
||||
atlas->TexID = (ImTextureID)NULL;
|
||||
atlas->TexWidth = atlas->TexHeight = 0;
|
||||
atlas->TexUvScale = ImVec2(0.0f, 0.0f);
|
||||
atlas->TexUvWhitePixel = ImVec2(0.0f, 0.0f);
|
||||
atlas->ClearTexData();
|
||||
|
||||
// Temporary storage for building
|
||||
bool src_load_color = false;
|
||||
ImVector<ImFontBuildSrcDataFT> src_tmp_array;
|
||||
ImVector<ImFontBuildDstDataFT> dst_tmp_array;
|
||||
src_tmp_array.resize(atlas->ConfigData.Size);
|
||||
dst_tmp_array.resize(atlas->Fonts.Size);
|
||||
memset((void*)src_tmp_array.Data, 0, (size_t)src_tmp_array.size_in_bytes());
|
||||
memset((void*)dst_tmp_array.Data, 0, (size_t)dst_tmp_array.size_in_bytes());
|
||||
|
||||
// 1. Initialize font loading structure, check font data validity
|
||||
for (int src_i = 0; src_i < atlas->ConfigData.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
FreeTypeFont& font_face = src_tmp.Font;
|
||||
IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas));
|
||||
|
||||
// Find index from cfg.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices)
|
||||
src_tmp.DstIndex = -1;
|
||||
for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++)
|
||||
if (cfg.DstFont == atlas->Fonts[output_i])
|
||||
src_tmp.DstIndex = output_i;
|
||||
IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array?
|
||||
if (src_tmp.DstIndex == -1)
|
||||
return false;
|
||||
|
||||
// Load font
|
||||
if (!font_face.InitFont(ft_library, cfg, extra_flags))
|
||||
return false;
|
||||
|
||||
// Measure highest codepoints
|
||||
src_load_color |= (cfg.FontBuilderFlags & ImGuiFreeTypeBuilderFlags_LoadColor) != 0;
|
||||
ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
|
||||
src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault();
|
||||
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
|
||||
src_tmp.GlyphsHighest = ImMax(src_tmp.GlyphsHighest, (int)src_range[1]);
|
||||
dst_tmp.SrcCount++;
|
||||
dst_tmp.GlyphsHighest = ImMax(dst_tmp.GlyphsHighest, src_tmp.GlyphsHighest);
|
||||
}
|
||||
|
||||
// 2. For every requested codepoint, check for their presence in the font data, and handle redundancy or overlaps between source fonts to avoid unused glyphs.
|
||||
int total_glyphs_count = 0;
|
||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
|
||||
src_tmp.GlyphsSet.Create(src_tmp.GlyphsHighest + 1);
|
||||
if (dst_tmp.GlyphsSet.Storage.empty())
|
||||
dst_tmp.GlyphsSet.Create(dst_tmp.GlyphsHighest + 1);
|
||||
|
||||
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
|
||||
for (int codepoint = src_range[0]; codepoint <= (int)src_range[1]; codepoint++)
|
||||
{
|
||||
if (dst_tmp.GlyphsSet.TestBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite)
|
||||
continue;
|
||||
uint32_t glyph_index = FT_Get_Char_Index(src_tmp.Font.Face, codepoint); // It is actually in the font? (FIXME-OPT: We are not storing the glyph_index..)
|
||||
if (glyph_index == 0)
|
||||
continue;
|
||||
|
||||
// Add to avail set/counters
|
||||
src_tmp.GlyphsCount++;
|
||||
dst_tmp.GlyphsCount++;
|
||||
src_tmp.GlyphsSet.SetBit(codepoint);
|
||||
dst_tmp.GlyphsSet.SetBit(codepoint);
|
||||
total_glyphs_count++;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Unpack our bit map into a flat list (we now have all the Unicode points that we know are requested _and_ available _and_ not overlapping another)
|
||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
src_tmp.GlyphsList.reserve(src_tmp.GlyphsCount);
|
||||
|
||||
IM_ASSERT(sizeof(src_tmp.GlyphsSet.Storage.Data[0]) == sizeof(ImU32));
|
||||
const ImU32* it_begin = src_tmp.GlyphsSet.Storage.begin();
|
||||
const ImU32* it_end = src_tmp.GlyphsSet.Storage.end();
|
||||
for (const ImU32* it = it_begin; it < it_end; it++)
|
||||
if (ImU32 entries_32 = *it)
|
||||
for (ImU32 bit_n = 0; bit_n < 32; bit_n++)
|
||||
if (entries_32 & ((ImU32)1 << bit_n))
|
||||
{
|
||||
ImFontBuildSrcGlyphFT src_glyph;
|
||||
src_glyph.Codepoint = (ImWchar)(((it - it_begin) << 5) + bit_n);
|
||||
//src_glyph.GlyphIndex = 0; // FIXME-OPT: We had this info in the previous step and lost it..
|
||||
src_tmp.GlyphsList.push_back(src_glyph);
|
||||
}
|
||||
src_tmp.GlyphsSet.Clear();
|
||||
IM_ASSERT(src_tmp.GlyphsList.Size == src_tmp.GlyphsCount);
|
||||
}
|
||||
for (int dst_i = 0; dst_i < dst_tmp_array.Size; dst_i++)
|
||||
dst_tmp_array[dst_i].GlyphsSet.Clear();
|
||||
dst_tmp_array.clear();
|
||||
|
||||
// Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0)
|
||||
// (We technically don't need to zero-clear buf_rects, but let's do it for the sake of sanity)
|
||||
ImVector<stbrp_rect> buf_rects;
|
||||
buf_rects.resize(total_glyphs_count);
|
||||
memset(buf_rects.Data, 0, (size_t)buf_rects.size_in_bytes());
|
||||
|
||||
// Allocate temporary rasterization data buffers.
|
||||
// We could not find a way to retrieve accurate glyph size without rendering them.
|
||||
// (e.g. slot->metrics->width not always matching bitmap->width, especially considering the Oblique transform)
|
||||
// We allocate in chunks of 256 KB to not waste too much extra memory ahead. Hopefully users of FreeType won't mind the temporary allocations.
|
||||
const int BITMAP_BUFFERS_CHUNK_SIZE = 256 * 1024;
|
||||
int buf_bitmap_current_used_bytes = 0;
|
||||
ImVector<unsigned char*> buf_bitmap_buffers;
|
||||
buf_bitmap_buffers.push_back((unsigned char*)IM_ALLOC(BITMAP_BUFFERS_CHUNK_SIZE));
|
||||
|
||||
// 4. Gather glyphs sizes so we can pack them in our virtual canvas.
|
||||
// 8. Render/rasterize font characters into the texture
|
||||
int total_surface = 0;
|
||||
int buf_rects_out_n = 0;
|
||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
if (src_tmp.GlyphsCount == 0)
|
||||
continue;
|
||||
|
||||
src_tmp.Rects = &buf_rects[buf_rects_out_n];
|
||||
buf_rects_out_n += src_tmp.GlyphsCount;
|
||||
|
||||
// Compute multiply table if requested
|
||||
const bool multiply_enabled = (cfg.RasterizerMultiply != 1.0f);
|
||||
unsigned char multiply_table[256];
|
||||
if (multiply_enabled)
|
||||
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply);
|
||||
|
||||
// Gather the sizes of all rectangles we will need to pack
|
||||
const int padding = atlas->TexGlyphPadding;
|
||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
|
||||
{
|
||||
ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i];
|
||||
|
||||
const FT_Glyph_Metrics* metrics = src_tmp.Font.LoadGlyph(src_glyph.Codepoint);
|
||||
if (metrics == NULL)
|
||||
continue;
|
||||
|
||||
// Render glyph into a bitmap (currently held by FreeType)
|
||||
const FT_Bitmap* ft_bitmap = src_tmp.Font.RenderGlyphAndGetInfo(&src_glyph.Info);
|
||||
if (ft_bitmap == NULL)
|
||||
continue;
|
||||
|
||||
// Allocate new temporary chunk if needed
|
||||
const int bitmap_size_in_bytes = src_glyph.Info.Width * src_glyph.Info.Height * 4;
|
||||
if (buf_bitmap_current_used_bytes + bitmap_size_in_bytes > BITMAP_BUFFERS_CHUNK_SIZE)
|
||||
{
|
||||
buf_bitmap_current_used_bytes = 0;
|
||||
buf_bitmap_buffers.push_back((unsigned char*)IM_ALLOC(BITMAP_BUFFERS_CHUNK_SIZE));
|
||||
}
|
||||
IM_ASSERT(buf_bitmap_current_used_bytes + bitmap_size_in_bytes <= BITMAP_BUFFERS_CHUNK_SIZE); // We could probably allocate custom-sized buffer instead.
|
||||
|
||||
// Blit rasterized pixels to our temporary buffer and keep a pointer to it.
|
||||
src_glyph.BitmapData = (unsigned int*)(buf_bitmap_buffers.back() + buf_bitmap_current_used_bytes);
|
||||
buf_bitmap_current_used_bytes += bitmap_size_in_bytes;
|
||||
src_tmp.Font.BlitGlyph(ft_bitmap, src_glyph.BitmapData, src_glyph.Info.Width, multiply_enabled ? multiply_table : NULL);
|
||||
|
||||
src_tmp.Rects[glyph_i].w = (stbrp_coord)(src_glyph.Info.Width + padding);
|
||||
src_tmp.Rects[glyph_i].h = (stbrp_coord)(src_glyph.Info.Height + padding);
|
||||
total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h;
|
||||
}
|
||||
}
|
||||
|
||||
// We need a width for the skyline algorithm, any width!
|
||||
// The exact width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height.
|
||||
// User can override TexDesiredWidth and TexGlyphPadding if they wish, otherwise we use a simple heuristic to select the width based on expected surface.
|
||||
const int surface_sqrt = (int)ImSqrt((float)total_surface) + 1;
|
||||
atlas->TexHeight = 0;
|
||||
if (atlas->TexDesiredWidth > 0)
|
||||
atlas->TexWidth = atlas->TexDesiredWidth;
|
||||
else
|
||||
atlas->TexWidth = (surface_sqrt >= 4096 * 0.7f) ? 4096 : (surface_sqrt >= 2048 * 0.7f) ? 2048 : (surface_sqrt >= 1024 * 0.7f) ? 1024 : 512;
|
||||
|
||||
// 5. Start packing
|
||||
// Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values).
|
||||
const int TEX_HEIGHT_MAX = 1024 * 32;
|
||||
const int num_nodes_for_packing_algorithm = atlas->TexWidth - atlas->TexGlyphPadding;
|
||||
ImVector<stbrp_node> pack_nodes;
|
||||
pack_nodes.resize(num_nodes_for_packing_algorithm);
|
||||
stbrp_context pack_context;
|
||||
stbrp_init_target(&pack_context, atlas->TexWidth - atlas->TexGlyphPadding, TEX_HEIGHT_MAX - atlas->TexGlyphPadding, pack_nodes.Data, pack_nodes.Size);
|
||||
ImFontAtlasBuildPackCustomRects(atlas, &pack_context);
|
||||
|
||||
// 6. Pack each source font. No rendering yet, we are working with rectangles in an infinitely tall texture at this point.
|
||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
if (src_tmp.GlyphsCount == 0)
|
||||
continue;
|
||||
|
||||
stbrp_pack_rects(&pack_context, src_tmp.Rects, src_tmp.GlyphsCount);
|
||||
|
||||
// Extend texture height and mark missing glyphs as non-packed so we won't render them.
|
||||
// FIXME: We are not handling packing failure here (would happen if we got off TEX_HEIGHT_MAX or if a single if larger than TexWidth?)
|
||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
|
||||
if (src_tmp.Rects[glyph_i].was_packed)
|
||||
atlas->TexHeight = ImMax(atlas->TexHeight, src_tmp.Rects[glyph_i].y + src_tmp.Rects[glyph_i].h);
|
||||
}
|
||||
|
||||
// 7. Allocate texture
|
||||
atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight);
|
||||
atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight);
|
||||
if (src_load_color)
|
||||
{
|
||||
size_t tex_size = (size_t)atlas->TexWidth * atlas->TexHeight * 4;
|
||||
atlas->TexPixelsRGBA32 = (unsigned int*)IM_ALLOC(tex_size);
|
||||
memset(atlas->TexPixelsRGBA32, 0, tex_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t tex_size = (size_t)atlas->TexWidth * atlas->TexHeight * 1;
|
||||
atlas->TexPixelsAlpha8 = (unsigned char*)IM_ALLOC(tex_size);
|
||||
memset(atlas->TexPixelsAlpha8, 0, tex_size);
|
||||
}
|
||||
|
||||
// 8. Copy rasterized font characters back into the main texture
|
||||
// 9. Setup ImFont and glyphs for runtime
|
||||
bool tex_use_colors = false;
|
||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
if (src_tmp.GlyphsCount == 0)
|
||||
continue;
|
||||
|
||||
// When merging fonts with MergeMode=true:
|
||||
// - We can have multiple input fonts writing into a same destination font.
|
||||
// - dst_font->ConfigData is != from cfg which is our source configuration.
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
ImFont* dst_font = cfg.DstFont;
|
||||
|
||||
const float ascent = src_tmp.Font.Info.Ascender;
|
||||
const float descent = src_tmp.Font.Info.Descender;
|
||||
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
|
||||
const float font_off_x = cfg.GlyphOffset.x;
|
||||
const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
|
||||
|
||||
const int padding = atlas->TexGlyphPadding;
|
||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
|
||||
{
|
||||
ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i];
|
||||
stbrp_rect& pack_rect = src_tmp.Rects[glyph_i];
|
||||
IM_ASSERT(pack_rect.was_packed);
|
||||
if (pack_rect.w == 0 && pack_rect.h == 0)
|
||||
continue;
|
||||
|
||||
GlyphInfo& info = src_glyph.Info;
|
||||
IM_ASSERT(info.Width + padding <= pack_rect.w);
|
||||
IM_ASSERT(info.Height + padding <= pack_rect.h);
|
||||
const int tx = pack_rect.x + padding;
|
||||
const int ty = pack_rect.y + padding;
|
||||
|
||||
// Register glyph
|
||||
float x0 = info.OffsetX + font_off_x;
|
||||
float y0 = info.OffsetY + font_off_y;
|
||||
float x1 = x0 + info.Width;
|
||||
float y1 = y0 + info.Height;
|
||||
float u0 = (tx) / (float)atlas->TexWidth;
|
||||
float v0 = (ty) / (float)atlas->TexHeight;
|
||||
float u1 = (tx + info.Width) / (float)atlas->TexWidth;
|
||||
float v1 = (ty + info.Height) / (float)atlas->TexHeight;
|
||||
dst_font->AddGlyph(&cfg, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX);
|
||||
|
||||
ImFontGlyph* dst_glyph = &dst_font->Glyphs.back();
|
||||
IM_ASSERT(dst_glyph->Codepoint == src_glyph.Codepoint);
|
||||
if (src_glyph.Info.IsColored)
|
||||
dst_glyph->Colored = tex_use_colors = true;
|
||||
|
||||
// Blit from temporary buffer to final texture
|
||||
size_t blit_src_stride = (size_t)src_glyph.Info.Width;
|
||||
size_t blit_dst_stride = (size_t)atlas->TexWidth;
|
||||
unsigned int* blit_src = src_glyph.BitmapData;
|
||||
if (atlas->TexPixelsAlpha8 != NULL)
|
||||
{
|
||||
unsigned char* blit_dst = atlas->TexPixelsAlpha8 + (ty * blit_dst_stride) + tx;
|
||||
for (int y = 0; y < info.Height; y++, blit_dst += blit_dst_stride, blit_src += blit_src_stride)
|
||||
for (int x = 0; x < info.Width; x++)
|
||||
blit_dst[x] = (unsigned char)((blit_src[x] >> IM_COL32_A_SHIFT) & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int* blit_dst = atlas->TexPixelsRGBA32 + (ty * blit_dst_stride) + tx;
|
||||
for (int y = 0; y < info.Height; y++, blit_dst += blit_dst_stride, blit_src += blit_src_stride)
|
||||
for (int x = 0; x < info.Width; x++)
|
||||
blit_dst[x] = blit_src[x];
|
||||
}
|
||||
}
|
||||
|
||||
src_tmp.Rects = NULL;
|
||||
}
|
||||
atlas->TexPixelsUseColors = tex_use_colors;
|
||||
|
||||
// Cleanup
|
||||
for (int buf_i = 0; buf_i < buf_bitmap_buffers.Size; buf_i++)
|
||||
IM_FREE(buf_bitmap_buffers[buf_i]);
|
||||
src_tmp_array.clear_destruct();
|
||||
|
||||
ImFontAtlasBuildFinish(atlas);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// FreeType memory allocation callbacks
|
||||
static void* FreeType_Alloc(FT_Memory /*memory*/, long size)
|
||||
{
|
||||
return GImGuiFreeTypeAllocFunc((size_t)size, GImGuiFreeTypeAllocatorUserData);
|
||||
}
|
||||
|
||||
static void FreeType_Free(FT_Memory /*memory*/, void* block)
|
||||
{
|
||||
GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData);
|
||||
}
|
||||
|
||||
static void* FreeType_Realloc(FT_Memory /*memory*/, long cur_size, long new_size, void* block)
|
||||
{
|
||||
// Implement realloc() as we don't ask user to provide it.
|
||||
if (block == NULL)
|
||||
return GImGuiFreeTypeAllocFunc((size_t)new_size, GImGuiFreeTypeAllocatorUserData);
|
||||
|
||||
if (new_size == 0)
|
||||
{
|
||||
GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (new_size > cur_size)
|
||||
{
|
||||
void* new_block = GImGuiFreeTypeAllocFunc((size_t)new_size, GImGuiFreeTypeAllocatorUserData);
|
||||
memcpy(new_block, block, (size_t)cur_size);
|
||||
GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData);
|
||||
return new_block;
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
static bool ImFontAtlasBuildWithFreeType(ImFontAtlas* atlas)
|
||||
{
|
||||
// FreeType memory management: https://www.freetype.org/freetype2/docs/design/design-4.html
|
||||
FT_MemoryRec_ memory_rec = {};
|
||||
memory_rec.user = NULL;
|
||||
memory_rec.alloc = &FreeType_Alloc;
|
||||
memory_rec.free = &FreeType_Free;
|
||||
memory_rec.realloc = &FreeType_Realloc;
|
||||
|
||||
// https://www.freetype.org/freetype2/docs/reference/ft2-module_management.html#FT_New_Library
|
||||
FT_Library ft_library;
|
||||
FT_Error error = FT_New_Library(&memory_rec, &ft_library);
|
||||
if (error != 0)
|
||||
return false;
|
||||
|
||||
// If you don't call FT_Add_Default_Modules() the rest of code may work, but FreeType won't use our custom allocator.
|
||||
FT_Add_Default_Modules(ft_library);
|
||||
|
||||
bool ret = ImFontAtlasBuildWithFreeTypeEx(ft_library, atlas, atlas->FontBuilderFlags);
|
||||
FT_Done_Library(ft_library);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const ImFontBuilderIO* ImGuiFreeType::GetBuilderForFreeType()
|
||||
{
|
||||
static ImFontBuilderIO io;
|
||||
io.FontBuilder_Build = ImFontAtlasBuildWithFreeType;
|
||||
return &io;
|
||||
}
|
||||
|
||||
void ImGuiFreeType::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data)
|
||||
{
|
||||
GImGuiFreeTypeAllocFunc = alloc_func;
|
||||
GImGuiFreeTypeFreeFunc = free_func;
|
||||
GImGuiFreeTypeAllocatorUserData = user_data;
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "imgui.h"
|
||||
|
||||
struct ImFontAtlas;
|
||||
struct ImFontBuilderIO;
|
||||
|
||||
enum ImGuiFreeTypeBuilderFlags
|
||||
{
|
||||
ImGuiFreeTypeBuilderFlags_NoHinting = 1 << 0,
|
||||
ImGuiFreeTypeBuilderFlags_NoAutoHint = 1 << 1,
|
||||
ImGuiFreeTypeBuilderFlags_ForceAutoHint = 1 << 2,
|
||||
ImGuiFreeTypeBuilderFlags_LightHinting = 1 << 3,
|
||||
ImGuiFreeTypeBuilderFlags_MonoHinting = 1 << 4,
|
||||
ImGuiFreeTypeBuilderFlags_Bold = 1 << 5,
|
||||
ImGuiFreeTypeBuilderFlags_Oblique = 1 << 6,
|
||||
ImGuiFreeTypeBuilderFlags_Monochrome = 1 << 7,
|
||||
ImGuiFreeTypeBuilderFlags_LoadColor = 1 << 8,
|
||||
ImGuiFreeTypeBuilderFlags_Bitmap = 1 << 9
|
||||
};
|
||||
|
||||
namespace ImGuiFreeType
|
||||
{
|
||||
IMGUI_API const ImFontBuilderIO* GetBuilderForFreeType();
|
||||
IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = NULL);
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
static inline bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int flags = 0) { atlas->FontBuilderIO = GetBuilderForFreeType(); atlas->FontBuilderFlags = flags; return atlas->Build(); }
|
||||
#endif
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,534 @@
|
||||
#include "../settings/functions.h"
|
||||
|
||||
void c_widget::text_colored(ImFont* font, const ImU32 col, std::string text)
|
||||
{
|
||||
gui->push_font(font);
|
||||
TextColored(ImColor(col), text.data());
|
||||
gui->pop_font();
|
||||
}
|
||||
|
||||
bool c_widget::begin_popup(std::string_view name, float size_w, const ImVec2& position)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
const ImGuiID id = window->GetID(name.data());
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
ImVec2 content_size;
|
||||
float current_position;
|
||||
|
||||
struct popup_state
|
||||
{
|
||||
bool window_opened, hovered;
|
||||
float begin_offset, alpha_popup;
|
||||
};
|
||||
|
||||
popup_state* state = gui->anim_container(&state, id);
|
||||
if (IsItemHovered() && g.IO.MouseClicked[1] || state->window_opened && (g.IO.MouseClicked[0] || g.IO.MouseClicked[1]) && !state->hovered) state->window_opened = !state->window_opened;
|
||||
|
||||
state->alpha_popup = ImClamp(state->alpha_popup + (gui->fixed_speed(5.f) * (state->window_opened ? 1.f : -1.f)), 0.f, 1.f);
|
||||
|
||||
gui->push_style_var(ImGuiStyleVar_Alpha, state->alpha_popup);
|
||||
gui->push_style_var(ImGuiStyleVar_WindowBorderSize, 1.f);
|
||||
gui->push_style_var(ImGuiStyleVar_WindowRounding, SCALE(set->c_child.rounding));
|
||||
|
||||
gui->push_style_color(ImGuiCol_WindowBg, gui->get_clr(clr->c_child.layout));
|
||||
gui->push_style_color(ImGuiCol_Border, gui->get_clr(clr->c_child.stroke));
|
||||
|
||||
gui->set_next_window_pos(g.LastItemData.Rect.GetBL() + position);
|
||||
gui->set_next_window_size(ImVec2(SCALE(size_w), content_size.y));
|
||||
|
||||
gui->begin((std::stringstream{} << id << " - popup").str().c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollWithMouse);
|
||||
|
||||
state->hovered = IsMouseHoveringRect(GetWindowPos(), GetWindowPos() + GetWindowSize());
|
||||
content_size = GetContentRegionAvail();
|
||||
|
||||
return state->window_opened;
|
||||
}
|
||||
|
||||
void c_widget::end_popup()
|
||||
{
|
||||
gui->end();
|
||||
|
||||
gui->pop_style_var(3);
|
||||
gui->pop_style_color(2);
|
||||
}
|
||||
|
||||
bool c_widget::set_tooltip(std::string_view tooltip_id, std::string_view tooltip_text)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
const ImGuiID id = window->GetID(tooltip_text.data());
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
ImVec2 content_size;
|
||||
|
||||
struct popup_state
|
||||
{
|
||||
bool show_tooltip, hovered;
|
||||
float begin_offset, alpha_popup;
|
||||
};
|
||||
|
||||
popup_state* state = gui->anim_container(&state, id);
|
||||
|
||||
if (IsItemHovered())
|
||||
state->show_tooltip = true;
|
||||
else
|
||||
state->show_tooltip = false;
|
||||
|
||||
state->alpha_popup = ImClamp(state->alpha_popup + (gui->fixed_speed(5.f) * (state->show_tooltip ? 1.f : -1.f)), 0.f, 1.f);
|
||||
|
||||
gui->push_style_var(ImGuiStyleVar_Alpha, state->alpha_popup);
|
||||
gui->push_style_var(ImGuiStyleVar_WindowBorderSize, 1.f);
|
||||
gui->push_style_var(ImGuiStyleVar_WindowRounding, set->c_element.rounding);
|
||||
|
||||
gui->push_style_color(ImGuiCol_WindowBg, gui->get_clr(clr->c_child.layout));
|
||||
gui->push_style_color(ImGuiCol_Border, gui->get_clr(clr->c_child.stroke));
|
||||
|
||||
gui->set_next_window_pos(ImGui::GetMousePos() + SCALE(20, 20));
|
||||
gui->set_next_window_size(ImVec2(CalcTextSize(tooltip_text.data()).x + SCALE(30), content_size.y));
|
||||
|
||||
gui->begin((std::stringstream{} << id << " - popup").str().c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollWithMouse);
|
||||
{
|
||||
|
||||
state->hovered = IsMouseHoveringRect(GetWindowPos(), GetWindowPos() + GetWindowSize());
|
||||
content_size = GetContentRegionAvail();
|
||||
|
||||
text_colored(set->c_font.icon[0], gui->get_clr(clr->c_other_clr.white_clr), "L");
|
||||
|
||||
gui->sameline(0, 10);
|
||||
|
||||
text_colored(set->c_font.inter_medium[0], gui->get_clr(clr->c_text.text_active), tooltip_id.data());
|
||||
|
||||
widget->separator();
|
||||
|
||||
text_colored(set->c_font.inter_medium[0], gui->get_clr(clr->c_text.text), tooltip_text.data());
|
||||
|
||||
gui->pop_style_var(3);
|
||||
gui->pop_style_color(2);
|
||||
|
||||
}
|
||||
gui->end();
|
||||
|
||||
return state->show_tooltip;
|
||||
}
|
||||
|
||||
void item_hande_shortcut(ImGuiID id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiInputFlags flags = g.NextItemData.ShortcutFlags;
|
||||
IM_ASSERT((flags & ~ImGuiInputFlags_SupportedBySetNextItemShortcut) == 0);
|
||||
|
||||
if (flags & ImGuiInputFlags_Tooltip)
|
||||
{
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasShortcut;
|
||||
g.LastItemData.Shortcut = g.NextItemData.Shortcut;
|
||||
}
|
||||
if (!Shortcut(g.NextItemData.Shortcut, flags & ImGuiInputFlags_SupportedByShortcut, id) || g.NavActivateId != 0) return;
|
||||
|
||||
g.NavActivateId = id;
|
||||
g.NavActivateFlags = ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_FromShortcut;
|
||||
|
||||
g.NavActivateDownId = g.NavActivatePressedId = id;
|
||||
NavHighlightActivated(id);
|
||||
}
|
||||
|
||||
void c_gui::push_font(ImFont* font)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (!font) font = GetDefaultFont();
|
||||
|
||||
SetCurrentFont(font);
|
||||
g.FontStack.push_back(font);
|
||||
g.CurrentWindow->DrawList->PushTextureID(font->ContainerAtlas->TexID);
|
||||
}
|
||||
|
||||
void c_gui::pop_font()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.CurrentWindow->DrawList->PopTextureID();
|
||||
g.FontStack.pop_back();
|
||||
|
||||
SetCurrentFont(g.FontStack.empty() ? GetDefaultFont() : g.FontStack.back());
|
||||
}
|
||||
|
||||
void c_gui::set_next_window_pos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasPos;
|
||||
g.NextWindowData.PosVal = pos;
|
||||
g.NextWindowData.PosPivotVal = ImVec2(ImClamp(pivot.x, 0.0f, 1.0f), ImClamp(pivot.y, 0.0f, 1.0f));
|
||||
g.NextWindowData.PosCond = (cond != 0 && ImIsPowerOfTwo(cond)) ? cond : ImGuiCond_Always;
|
||||
}
|
||||
void c_gui::set_next_window_size(const ImVec2& size, ImGuiCond cond)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(size.x >= 0.0f && size.y >= 0.0f);
|
||||
IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond));
|
||||
|
||||
g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasSize;
|
||||
g.NextWindowData.SizeVal = size;
|
||||
g.NextWindowData.SizeCond = cond != 0 ? cond : ImGuiCond_Always;
|
||||
}
|
||||
|
||||
ImVec2 c_gui::get_cursor_pos()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
return window->DC.CursorPos - window->Pos + window->Scroll;
|
||||
}
|
||||
|
||||
float c_gui::get_cursor_pos_x()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
return window->DC.CursorPos.x - window->Pos.x + window->Scroll.x;
|
||||
}
|
||||
|
||||
float c_gui::get_cursor_pos_y()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
return window->DC.CursorPos.y - window->Pos.y + window->Scroll.y;
|
||||
}
|
||||
|
||||
|
||||
void c_gui::set_cursor_pos(const ImVec2& local_pos)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
window->DC.CursorPos = window->Pos - window->Scroll + local_pos;
|
||||
window->DC.IsSetPos = true;
|
||||
}
|
||||
|
||||
void c_gui::set_cursor_pos_x(float x)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + x;
|
||||
window->DC.IsSetPos = true;
|
||||
}
|
||||
|
||||
void c_gui::set_cursor_pos_y(float y)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
window->DC.CursorPos.y = window->Pos.y - window->Scroll.y + y;
|
||||
window->DC.IsSetPos = true;
|
||||
}
|
||||
|
||||
void c_gui::new_frame()
|
||||
{
|
||||
NewFrame();
|
||||
}
|
||||
|
||||
void c_gui::end_frame()
|
||||
{
|
||||
Render();
|
||||
}
|
||||
|
||||
ImU32 c_gui::get_clr(const ImVec4& col, float alpha)
|
||||
{
|
||||
ImVec4 c = col;
|
||||
c.w *= GetStyle().Alpha * alpha;
|
||||
return ColorConvertFloat4ToU32(c);
|
||||
}
|
||||
|
||||
void c_gui::push_style_color(ImGuiCol idx, ImU32 col)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiColorMod backup;
|
||||
backup.Col = idx;
|
||||
backup.BackupValue = g.Style.Colors[idx];
|
||||
g.ColorStack.push_back(backup);
|
||||
if (g.DebugFlashStyleColorIdx != idx) g.Style.Colors[idx] = ColorConvertU32ToFloat4(col);
|
||||
}
|
||||
|
||||
void c_gui::pop_style_color(int count)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.ColorStack.Size < count)
|
||||
{
|
||||
count = g.ColorStack.Size;
|
||||
}
|
||||
while (count > 0)
|
||||
{
|
||||
ImGuiColorMod& backup = g.ColorStack.back();
|
||||
g.Style.Colors[backup.Col] = backup.BackupValue;
|
||||
g.ColorStack.pop_back();
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
void c_gui::push_style_var(ImGuiStyleVar idx, float val)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx);
|
||||
if (var_info->Type == ImGuiDataType_Float && var_info->Count == 1)
|
||||
{
|
||||
float* pvar = (float*)var_info->GetVarPtr(&g.Style);
|
||||
g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar));
|
||||
*pvar = val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void c_gui::push_style_var(ImGuiStyleVar idx, const ImVec2& val)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx);
|
||||
if (var_info->Type == ImGuiDataType_Float && var_info->Count == 2)
|
||||
{
|
||||
ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&g.Style);
|
||||
g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar));
|
||||
*pvar = val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void c_gui::pop_style_var(int count)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.StyleVarStack.Size < count)
|
||||
{
|
||||
count = g.StyleVarStack.Size;
|
||||
}
|
||||
while (count > 0)
|
||||
{
|
||||
ImGuiStyleMod& backup = g.StyleVarStack.back();
|
||||
const ImGuiDataVarInfo* info = GetStyleVarInfo(backup.VarIdx);
|
||||
void* data = info->GetVarPtr(&g.Style);
|
||||
if (info->Type == ImGuiDataType_Float && info->Count == 1) { ((float*)data)[0] = backup.BackupFloat[0]; }
|
||||
else if (info->Type == ImGuiDataType_Float && info->Count == 2) { ((float*)data)[0] = backup.BackupFloat[0]; ((float*)data)[1] = backup.BackupFloat[1]; }
|
||||
g.StyleVarStack.pop_back();
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
void c_gui::spacing()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems) return;
|
||||
ImGui::ItemSize(ImVec2(0, 0));
|
||||
}
|
||||
|
||||
void c_gui::sameline(float offset_from_start_x, float spacing_w)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (window->SkipItems) return;
|
||||
|
||||
if (offset_from_start_x != 0.0f)
|
||||
{
|
||||
if (spacing_w < 0.0f) spacing_w = 0.0f;
|
||||
window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + offset_from_start_x + spacing_w + window->DC.GroupOffset.x + window->DC.ColumnsOffset.x;
|
||||
window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (spacing_w < 0.0f) spacing_w = GetStyle().ItemSpacing.x;
|
||||
|
||||
window->DC.CursorPos.x = window->DC.CursorPosPrevLine.x + spacing_w;
|
||||
window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y;
|
||||
}
|
||||
window->DC.CurrLineSize = window->DC.PrevLineSize;
|
||||
window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset;
|
||||
window->DC.IsSameLine = true;
|
||||
}
|
||||
|
||||
void c_gui::begin_group()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
g.GroupStack.resize(g.GroupStack.Size + 1);
|
||||
ImGuiGroupData& group_data = g.GroupStack.back();
|
||||
group_data.WindowID = window->ID;
|
||||
group_data.BackupCursorPos = window->DC.CursorPos;
|
||||
group_data.BackupCursorPosPrevLine = window->DC.CursorPosPrevLine;
|
||||
group_data.BackupCursorMaxPos = window->DC.CursorMaxPos;
|
||||
group_data.BackupIndent = window->DC.Indent;
|
||||
group_data.BackupGroupOffset = window->DC.GroupOffset;
|
||||
group_data.BackupCurrLineSize = window->DC.CurrLineSize;
|
||||
group_data.BackupCurrLineTextBaseOffset = window->DC.CurrLineTextBaseOffset;
|
||||
group_data.BackupActiveIdIsAlive = g.ActiveIdIsAlive;
|
||||
group_data.BackupHoveredIdIsAlive = g.HoveredId != 0;
|
||||
group_data.BackupIsSameLine = window->DC.IsSameLine;
|
||||
group_data.BackupActiveIdPreviousFrameIsAlive = g.ActiveIdPreviousFrameIsAlive;
|
||||
group_data.EmitItem = true;
|
||||
|
||||
window->DC.GroupOffset.x = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffset.x;
|
||||
window->DC.Indent = window->DC.GroupOffset;
|
||||
window->DC.CursorMaxPos = window->DC.CursorPos;
|
||||
window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
|
||||
if (g.LogEnabled) g.LogLinePosY = -FLT_MAX;
|
||||
}
|
||||
|
||||
void c_gui::end_group()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
IM_ASSERT(g.GroupStack.Size > 0);
|
||||
|
||||
ImGuiGroupData& group_data = g.GroupStack.back();
|
||||
IM_ASSERT(group_data.WindowID == window->ID);
|
||||
|
||||
if (window->DC.IsSetPos) ErrorCheckUsingSetCursorPosToExtendParentBoundaries();
|
||||
|
||||
ImRect group_bb(group_data.BackupCursorPos, ImMax(window->DC.CursorMaxPos, group_data.BackupCursorPos));
|
||||
|
||||
window->DC.CursorPos = group_data.BackupCursorPos;
|
||||
window->DC.CursorPosPrevLine = group_data.BackupCursorPosPrevLine;
|
||||
window->DC.CursorMaxPos = ImMax(group_data.BackupCursorMaxPos, window->DC.CursorMaxPos);
|
||||
window->DC.Indent = group_data.BackupIndent;
|
||||
window->DC.GroupOffset = group_data.BackupGroupOffset;
|
||||
window->DC.CurrLineSize = group_data.BackupCurrLineSize;
|
||||
window->DC.CurrLineTextBaseOffset = group_data.BackupCurrLineTextBaseOffset;
|
||||
window->DC.IsSameLine = group_data.BackupIsSameLine;
|
||||
if (g.LogEnabled) g.LogLinePosY = -FLT_MAX;
|
||||
|
||||
if (!group_data.EmitItem)
|
||||
{
|
||||
g.GroupStack.pop_back();
|
||||
return;
|
||||
}
|
||||
|
||||
window->DC.CurrLineTextBaseOffset = ImMax(window->DC.PrevLineTextBaseOffset, group_data.BackupCurrLineTextBaseOffset);
|
||||
ImGui::ItemSize(group_bb.GetSize());
|
||||
ItemAdd(group_bb, 0, NULL, ImGuiItemFlags_NoTabStop);
|
||||
|
||||
const bool group_contains_curr_active_id = (group_data.BackupActiveIdIsAlive != g.ActiveId) && (g.ActiveIdIsAlive == g.ActiveId) && g.ActiveId;
|
||||
const bool group_contains_prev_active_id = (group_data.BackupActiveIdPreviousFrameIsAlive == false) && (g.ActiveIdPreviousFrameIsAlive == true);
|
||||
if (group_contains_curr_active_id) g.LastItemData.ID = g.ActiveId;
|
||||
else if (group_contains_prev_active_id) g.LastItemData.ID = g.ActiveIdPreviousFrame;
|
||||
g.LastItemData.Rect = group_bb;
|
||||
|
||||
const bool group_contains_curr_hovered_id = (group_data.BackupHoveredIdIsAlive == false) && g.HoveredId != 0;
|
||||
if (group_contains_curr_hovered_id) g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
||||
|
||||
if (group_contains_curr_active_id && g.ActiveIdHasBeenEditedThisFrame) g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited;
|
||||
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasDeactivated;
|
||||
if (group_contains_prev_active_id && g.ActiveId != g.ActiveIdPreviousFrame) g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Deactivated;
|
||||
|
||||
g.GroupStack.pop_back();
|
||||
if (g.DebugShowGroupRects) window->DrawList->AddRect(group_bb.Min, group_bb.Max, IM_COL32(255, 0, 255, 255));
|
||||
}
|
||||
|
||||
void c_widget::separator()
|
||||
{
|
||||
draw->add_line(GetWindowDrawList(), GetCursorScreenPos(), GetCursorScreenPos() + ImVec2(GetContentRegionAvail().x, 0), gui->get_clr(clr->c_element.separator), 1.f);
|
||||
gui->spacing();
|
||||
}
|
||||
|
||||
void c_gui::water_mark(std::string name, std::vector<std::string> function, watermark_position type, bool* visible)
|
||||
{
|
||||
static ImVec2 content_size, pos, current_pos;
|
||||
|
||||
struct spectator_state
|
||||
{
|
||||
float alpha;
|
||||
};
|
||||
|
||||
spectator_state* state = gui->anim_container(&state, ImGui::GetID(name.c_str()));
|
||||
|
||||
state->alpha = ImLerp(state->alpha, *visible ? 1.f : 0.f, fixed_speed(12.f));
|
||||
|
||||
push_style_var(ImGuiStyleVar_Alpha, state->alpha);
|
||||
|
||||
if (state->alpha >= 0.01f) {
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case mark_top_left:
|
||||
pos = SCALE(10, 10);
|
||||
break;
|
||||
case mark_top_right:
|
||||
pos = ImVec2(ImGui::GetIO().DisplaySize.x - content_size.x, SCALE(10));
|
||||
break;
|
||||
case mark_bottom_left:
|
||||
pos = ImVec2(SCALE(10), ImGui::GetIO().DisplaySize.y - content_size.y);
|
||||
break;
|
||||
case mark_bottom_right:
|
||||
pos = ImVec2(ImGui::GetIO().DisplaySize.x - content_size.x, ImGui::GetIO().DisplaySize.y - content_size.y);
|
||||
break;
|
||||
}
|
||||
|
||||
current_pos = ImLerp(current_pos, pos, fixed_speed(25.f));
|
||||
|
||||
gui->push_style_color(ImGuiCol_WindowBg, gui->get_clr(clr->c_window.layout));
|
||||
gui->push_style_var(ImGuiStyleVar_WindowRounding, SCALE(4.f));
|
||||
gui->push_style_var(ImGuiStyleVar_WindowPadding, SCALE(10, 10));
|
||||
gui->push_style_var(ImGuiStyleVar_ItemSpacing, SCALE(20, 10));
|
||||
|
||||
SetNextWindowPos(current_pos);
|
||||
gui->begin("watermark", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize);
|
||||
{
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
for (int i = 0; i < function.size(); i++)
|
||||
{
|
||||
widget->text_colored(set->c_font.inter_medium[0], gui->get_clr(i == 0 ? clr->c_text.text_active : clr->c_text.text), function[i]);
|
||||
gui->sameline();
|
||||
draw->add_rect_filled(draw_list, ImGui::GetCursorScreenPos() - SCALE(12, 0), ImGui::GetCursorScreenPos() + SCALE(-9, 14), gui->get_clr(clr->c_child.stroke), 10.f);
|
||||
gui->sameline();
|
||||
}
|
||||
|
||||
content_size = ImGui::GetContentRegionMax() + SCALE(20, 20);
|
||||
}
|
||||
gui->end();
|
||||
|
||||
gui->pop_style_var(3);
|
||||
gui->pop_style_color(1);
|
||||
|
||||
}
|
||||
pop_style_var();
|
||||
}
|
||||
|
||||
#include <chrono>
|
||||
|
||||
std::string c_gui::get_current_date()
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
std::time_t now_time = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
std::tm* now_tm = std::localtime(&now_time);
|
||||
|
||||
std::ostringstream date_stream;
|
||||
date_stream << std::setfill('0') << std::setw(2) << now_tm->tm_mday << '/'
|
||||
<< std::setfill('0') << std::setw(2) << (now_tm->tm_mon + 1) << '/'
|
||||
<< std::setfill('0') << std::setw(2) << (now_tm->tm_year % 100);
|
||||
|
||||
return date_stream.str();
|
||||
}
|
||||
|
||||
int rotation_start_index;
|
||||
void c_gui::rotate_start()
|
||||
{
|
||||
rotation_start_index = ImGui::GetWindowDrawList()->VtxBuffer.Size;
|
||||
}
|
||||
|
||||
ImVec2 rotate_center()
|
||||
{
|
||||
ImVec2 l(FLT_MAX, FLT_MAX), u(-FLT_MAX, -FLT_MAX); // bounds
|
||||
|
||||
const auto& buf = ImGui::GetWindowDrawList()->VtxBuffer;
|
||||
for (int i = rotation_start_index; i < buf.Size; i++)
|
||||
l = ImMin(l, buf[i].pos), u = ImMax(u, buf[i].pos);
|
||||
|
||||
return ImVec2((l.x + u.x) / 2, (l.y + u.y) / 2); // or use _ClipRectStack?
|
||||
}
|
||||
|
||||
void c_gui::rotate_end(float rad, ImVec2 center)
|
||||
{
|
||||
if (center.x == 0 && center.y == 0) center = rotate_center();
|
||||
|
||||
float s = sin(rad), c = cos(rad);
|
||||
center = ImRotate(center, s, c) - center;
|
||||
|
||||
auto& buf = ImGui::GetWindowDrawList()->VtxBuffer;
|
||||
for (int i = rotation_start_index; i < buf.Size; i++)
|
||||
buf[i].pos = ImRotate(buf[i].pos, s, c) - center;
|
||||
}
|
||||
|
||||
float c_gui::deg_to_rad(float deg)
|
||||
{
|
||||
return deg / 57.3f;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,226 @@
|
||||
#include "../settings/functions.h"
|
||||
|
||||
bool begin_child_ex(const char* name, ImGuiID id, const ImVec2& size_arg, ImGuiChildFlags child_flags, ImGuiWindowFlags window_flags)
|
||||
{
|
||||
struct c_child
|
||||
{
|
||||
float state{ 0 };
|
||||
float slow{ 0.f };
|
||||
};
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* parent_window = g.CurrentWindow;
|
||||
IM_ASSERT(id != 0);
|
||||
|
||||
const ImGuiChildFlags ImGuiChildFlags_SupportedMask_ = ImGuiChildFlags_Border | ImGuiChildFlags_AlwaysUseWindowPadding | ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_FrameStyle;
|
||||
IM_UNUSED(ImGuiChildFlags_SupportedMask_);
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
if (window_flags & ImGuiWindowFlags_AlwaysUseWindowPadding) child_flags |= ImGuiChildFlags_AlwaysUseWindowPadding;
|
||||
#endif
|
||||
|
||||
if (child_flags & ImGuiChildFlags_AutoResizeX) child_flags &= ~ImGuiChildFlags_ResizeX;
|
||||
if (child_flags & ImGuiChildFlags_AutoResizeY) child_flags &= ~ImGuiChildFlags_ResizeY;
|
||||
|
||||
window_flags |= ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoTitleBar;
|
||||
window_flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove);
|
||||
|
||||
if (child_flags & (ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_AlwaysAutoResize)) window_flags |= ImGuiWindowFlags_AlwaysAutoResize;
|
||||
if ((child_flags & (ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY)) == 0) window_flags |= ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings;
|
||||
|
||||
g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasChildFlags;
|
||||
g.NextWindowData.ChildFlags = child_flags;
|
||||
|
||||
const ImVec2 size_avail = GetContentRegionAvail();
|
||||
const ImVec2 size_default((child_flags & ImGuiChildFlags_AutoResizeX) ? 0.0f : size_avail.x, (child_flags & ImGuiChildFlags_AutoResizeY) ? 0.0f : size_avail.y);
|
||||
|
||||
c_child* state = gui->anim_container(&state, id);
|
||||
|
||||
ImVec2 size = size_arg;
|
||||
if (size.x <= 0) size.x = (GetContentRegionMax().x - (GetScrollMaxY() > 0.f ? SCALE(set->c_window.scrollbar_size + 3) : SCALE(set->c_child.child_window_padding.x) * 3)) / 2;
|
||||
if (size.y <= 0) size.y = state->state + SCALE(set->c_child.child_window_padding.y) * 2;
|
||||
|
||||
gui->set_next_window_size(size);
|
||||
|
||||
draw->add_rect_filled(parent_window->DrawList, parent_window->DC.CursorPos, parent_window->DC.CursorPos + size, gui->get_clr(clr->c_child.layout), SCALE(set->c_child.rounding));
|
||||
draw->add_rect(parent_window->DrawList, parent_window->DC.CursorPos, parent_window->DC.CursorPos + size, gui->get_clr(clr->c_child.stroke), SCALE(set->c_child.rounding));
|
||||
|
||||
const char* temp_window_name;
|
||||
|
||||
if (name)
|
||||
ImFormatStringToTempBuffer(&temp_window_name, NULL, "%s/%s_%08X", parent_window->Name, name, id);
|
||||
else
|
||||
ImFormatStringToTempBuffer(&temp_window_name, NULL, "%s/%08X", parent_window->Name, id);
|
||||
|
||||
const bool ret = gui->begin(temp_window_name, NULL, window_flags);
|
||||
|
||||
ImGuiWindow* child_window = g.CurrentWindow;
|
||||
child_window->ChildId = id;
|
||||
|
||||
state->state = child_window->ContentSize.y;
|
||||
|
||||
if (child_window->BeginCount == 1) parent_window->DC.CursorPos = child_window->Pos;
|
||||
|
||||
const ImGuiID temp_id_for_activation = ImHashStr("##Child", 0, id);
|
||||
if (g.ActiveId == temp_id_for_activation) ClearActiveID();
|
||||
|
||||
if (g.NavActivateId == id && !(window_flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY))
|
||||
{
|
||||
FocusWindow(child_window);
|
||||
NavInitWindow(child_window, false);
|
||||
SetActiveID(temp_id_for_activation, child_window);
|
||||
g.ActiveIdSource = g.NavInputSource;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool c_gui::begin_child(std::string_view name, const ImVec2& size_arg, ImGuiChildFlags child_flags, ImGuiWindowFlags window_flags)
|
||||
{
|
||||
ImGuiID id = GetCurrentWindow()->GetID(name.data());
|
||||
|
||||
push_style_var(ImGuiStyleVar_WindowPadding, SCALE(set->c_child.child_window_padding));
|
||||
push_style_var(ImGuiStyleVar_ItemSpacing, SCALE(set->c_child.child_item_spacing));
|
||||
|
||||
return begin_child_ex(name.data(), id, size_arg, child_flags, window_flags | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||
}
|
||||
|
||||
void c_gui::end_child()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* child_window = g.CurrentWindow;
|
||||
|
||||
pop_style_var(2);
|
||||
|
||||
IM_ASSERT(g.WithinEndChild == false);
|
||||
IM_ASSERT(child_window->Flags & ImGuiWindowFlags_ChildWindow);
|
||||
|
||||
g.WithinEndChild = true;
|
||||
ImVec2 child_size = child_window->Size;
|
||||
gui->end();
|
||||
|
||||
if (child_window->BeginCount == 1)
|
||||
{
|
||||
ImGuiWindow* parent_window = g.CurrentWindow;
|
||||
ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + child_size);
|
||||
|
||||
ItemSize(child_size);
|
||||
|
||||
if (child_window->Flags & ImGuiWindowFlags_NavFlattened) parent_window->DC.NavLayersActiveMaskNext |= child_window->DC.NavLayersActiveMaskNext;
|
||||
|
||||
if (g.HoveredWindow == child_window) g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
||||
}
|
||||
g.WithinEndChild = false;
|
||||
g.LogLinePosY = -FLT_MAX;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool begin_def_child_ex(const char* name, ImGuiID id, const ImVec2& size_arg, ImGuiChildFlags child_flags, ImGuiWindowFlags window_flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* parent_window = g.CurrentWindow;
|
||||
IM_ASSERT(id != 0);
|
||||
|
||||
const ImGuiChildFlags ImGuiChildFlags_SupportedMask_ = ImGuiChildFlags_Border | ImGuiChildFlags_AlwaysUseWindowPadding | ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_FrameStyle;
|
||||
IM_UNUSED(ImGuiChildFlags_SupportedMask_);
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
if (window_flags & ImGuiWindowFlags_AlwaysUseWindowPadding) child_flags |= ImGuiChildFlags_AlwaysUseWindowPadding;
|
||||
#endif
|
||||
|
||||
if (child_flags & ImGuiChildFlags_AutoResizeX) child_flags &= ~ImGuiChildFlags_ResizeX;
|
||||
if (child_flags & ImGuiChildFlags_AutoResizeY) child_flags &= ~ImGuiChildFlags_ResizeY;
|
||||
|
||||
window_flags |= ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoTitleBar;
|
||||
window_flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove);
|
||||
|
||||
if (child_flags & (ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_AlwaysAutoResize)) window_flags |= ImGuiWindowFlags_AlwaysAutoResize;
|
||||
if ((child_flags & (ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY)) == 0) window_flags |= ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings;
|
||||
|
||||
g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasChildFlags;
|
||||
g.NextWindowData.ChildFlags = child_flags;
|
||||
|
||||
const ImVec2 size_avail = GetContentRegionAvail();
|
||||
const ImVec2 size_default((child_flags & ImGuiChildFlags_AutoResizeX) ? 0.0f : size_avail.x, (child_flags & ImGuiChildFlags_AutoResizeY) ? 0.0f : size_avail.y);
|
||||
const ImVec2 size = CalcItemSize(size_arg, size_default.x, size_default.y);
|
||||
|
||||
gui->set_next_window_size(size);
|
||||
|
||||
// draw->add_rect(GetForegroundDrawList(), parent_window->DC.CursorPos, parent_window->DC.CursorPos + size, gui->get_clr(clr->c_other_clr.white_clr), 0.f);
|
||||
|
||||
const char* temp_window_name;
|
||||
|
||||
if (name)
|
||||
ImFormatStringToTempBuffer(&temp_window_name, NULL, "%s/%s_%08X", parent_window->Name, name, id);
|
||||
else
|
||||
ImFormatStringToTempBuffer(&temp_window_name, NULL, "%s/%08X", parent_window->Name, id);
|
||||
|
||||
const bool ret = gui->begin(temp_window_name, NULL, window_flags);
|
||||
|
||||
ImGuiWindow* child_window = g.CurrentWindow;
|
||||
child_window->ChildId = id;
|
||||
|
||||
if (child_window->BeginCount == 1) parent_window->DC.CursorPos = child_window->Pos;
|
||||
|
||||
const ImGuiID temp_id_for_activation = ImHashStr("##Child", 0, id);
|
||||
if (g.ActiveId == temp_id_for_activation) ClearActiveID();
|
||||
|
||||
if (g.NavActivateId == id && !(window_flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY))
|
||||
{
|
||||
FocusWindow(child_window);
|
||||
NavInitWindow(child_window, false);
|
||||
SetActiveID(temp_id_for_activation, child_window);
|
||||
g.ActiveIdSource = g.NavInputSource;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool begin_def_child(std::string_view name, const ImVec2& size_arg, ImGuiChildFlags child_flags, ImGuiWindowFlags window_flags)
|
||||
{
|
||||
ImGuiID id = GetCurrentWindow()->GetID(name.data());
|
||||
return begin_def_child_ex(name.data(), id, size_arg, child_flags, window_flags);
|
||||
}
|
||||
|
||||
void end_def_child()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* child_window = g.CurrentWindow;
|
||||
|
||||
IM_ASSERT(g.WithinEndChild == false);
|
||||
IM_ASSERT(child_window->Flags & ImGuiWindowFlags_ChildWindow);
|
||||
|
||||
g.WithinEndChild = true;
|
||||
ImVec2 child_size = child_window->Size;
|
||||
gui->end();
|
||||
|
||||
if (child_window->BeginCount == 1)
|
||||
{
|
||||
ImGuiWindow* parent_window = g.CurrentWindow;
|
||||
ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + child_size);
|
||||
ItemSize(child_size);
|
||||
|
||||
if (child_window->Flags & ImGuiWindowFlags_NavFlattened) parent_window->DC.NavLayersActiveMaskNext |= child_window->DC.NavLayersActiveMaskNext;
|
||||
|
||||
if (g.HoveredWindow == child_window) g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
||||
}
|
||||
g.WithinEndChild = false;
|
||||
g.LogLinePosY = -FLT_MAX;
|
||||
}
|
||||
|
||||
void c_gui::begin_content(const char* id, const ImVec2& size_arg, const ImVec2& padding, const ImVec2& spacing)
|
||||
{
|
||||
push_style_var(ImGuiStyleVar_WindowPadding, SCALE(padding));
|
||||
push_style_var(ImGuiStyleVar_ItemSpacing, SCALE(spacing));
|
||||
|
||||
begin_def_child_ex(id, GetCurrentWindow()->GetID(id), size_arg, ImGuiChildFlags_None, ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus | (set->c_window.slider_hovered ? ImGuiWindowFlags_NoScrollWithMouse : 0));
|
||||
}
|
||||
|
||||
void c_gui::end_content()
|
||||
{
|
||||
end_def_child();
|
||||
pop_style_var(2);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
#include "../settings/functions.h"
|
||||
|
||||
bool c_widget::button(std::string_view label, const ImVec2& size)
|
||||
{
|
||||
struct button_state
|
||||
{
|
||||
ImVec4 background;
|
||||
};
|
||||
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label.data());
|
||||
|
||||
const float label_size = CalcTextSize(label.data(), NULL, true).x;
|
||||
const float width = GetContentRegionAvail().x;
|
||||
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
ImRect rect(pos, pos + size);
|
||||
|
||||
ItemSize(rect, 0);
|
||||
if (!ItemAdd(rect, id)) return false;
|
||||
|
||||
bool hovered, held, pressed = ButtonBehavior(rect, id, &hovered, &held);
|
||||
|
||||
if (pressed) MarkItemEdited(id);
|
||||
|
||||
button_state* state = gui->anim_container(&state, id);
|
||||
state->background = ImLerp(state->background, IsItemActive() ? clr->c_other_clr.accent_clr : clr->c_element.layout, gui->fixed_speed(8.f));
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max, gui->get_clr(state->background), SCALE(set->c_element.rounding));
|
||||
draw->render_text(set->c_font.inter_medium[0], window->DrawList, rect.Min, rect.Max, gui->get_clr(clr->c_text.text_active), label.data(), NULL, NULL, {0.5, 0.5}, NULL);
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool c_widget::tool_button(std::string_view label, std::string_view icon, const ImVec2& size) {
|
||||
struct tool_button {
|
||||
bool clicked = false;
|
||||
float alpha = 0.f;
|
||||
};
|
||||
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label.data());
|
||||
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
ImRect rect(pos, pos + size);
|
||||
|
||||
ItemSize(rect, 0);
|
||||
if (!ItemAdd(rect, id)) return false;
|
||||
|
||||
bool hovered, held, pressed = ButtonBehavior(rect, id, &hovered, &held);
|
||||
|
||||
tool_button* state = gui->anim_container(&state, id);
|
||||
|
||||
if (pressed)
|
||||
state->clicked = true;
|
||||
|
||||
state->alpha = ImClamp(state->alpha + (gui->fixed_speed(8.f) * (state->clicked ? 1.f : -1.f)), 0.f, 1.f);
|
||||
|
||||
if (state->alpha >= 0.99f)
|
||||
state->clicked = false;
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max, gui->get_clr(clr->c_lua.stroke), SCALE(2.f));
|
||||
draw->render_text(window->DrawList, set->c_font.inter_medium[1], rect.Min, rect.Max, gui->get_clr(clr->c_text.text), label.data(), NULL, NULL, ImVec2(0.5f, 0.5f));
|
||||
|
||||
if (icon != "")
|
||||
draw->render_text(window->DrawList, set->c_font.icon[4], rect.Min, rect.Max, gui->get_clr(clr->c_text.text), "D", NULL, NULL, ImVec2(0.18f, 0.5f));
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max, gui->get_clr(clr->c_other_clr.accent_clr, 1.f - state->alpha), SCALE(2.f));
|
||||
draw->render_text(window->DrawList, set->c_font.inter_medium[1], rect.Min, rect.Max, gui->get_clr(clr->c_text.text_active, 1.f - state->alpha), label.data(), NULL, NULL, ImVec2(icon != "" ? 0.7f : 0.5f, 0.5f));
|
||||
|
||||
if (icon != "")
|
||||
draw->render_text(window->DrawList, set->c_font.icon[4], rect.Min, rect.Max, gui->get_clr(clr->c_text.text_active, 1.f - state->alpha), "D", NULL, NULL, ImVec2(0.18f, 0.5f));
|
||||
|
||||
return pressed;
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
#include "../settings/functions.h"
|
||||
|
||||
bool c_widget::checkbox(std::string_view label, bool* callback)
|
||||
{
|
||||
struct c_checkbox
|
||||
{
|
||||
ImVec4 background = clr->c_element.layout;
|
||||
|
||||
ImVec4 text_colored = clr->c_text.text;
|
||||
ImVec4 circle = clr->c_element.circle;
|
||||
|
||||
float circle_offset = 0;
|
||||
};
|
||||
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label.data());
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label.data(), NULL, true);
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
|
||||
const float w = GetContentRegionAvail().x;
|
||||
const float h = SCALE(30);
|
||||
|
||||
const ImRect clickable_rect(pos, pos + ImVec2(w, h));
|
||||
const ImRect rect(pos + ImVec2(w - SCALE(40), SCALE(4)), pos + ImVec2(w, h - SCALE(4)));
|
||||
|
||||
ItemSize(clickable_rect, 0.f);
|
||||
if (!ItemAdd(clickable_rect, id)) return false;
|
||||
|
||||
bool hovered, held, pressed = ButtonBehavior(clickable_rect, id, &hovered, &held);
|
||||
|
||||
c_checkbox* state = gui->anim_container(&state, id);
|
||||
state->text_colored = ImLerp(state->text_colored, *callback ? clr->c_text.text_active : hovered ? clr->c_text.text_hov : clr->c_text.text, ImGui::GetIO().DeltaTime * 8.f);
|
||||
state->background = ImLerp(state->background, *callback ? clr->c_element.checkbox_active : clr->c_element.layout, ImGui::GetIO().DeltaTime * 8.f);
|
||||
|
||||
state->circle = ImLerp(state->circle, *callback ? clr->c_other_clr.accent_clr : clr->c_element.circle, ImGui::GetIO().DeltaTime * 8.f);
|
||||
state->circle_offset = ImLerp(state->circle_offset, *callback ? 28.f : 12.f, gui->fixed_speed(30.f));
|
||||
|
||||
if (pressed)
|
||||
{
|
||||
*callback = !(*callback);
|
||||
MarkItemEdited(id);
|
||||
}
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max, gui->get_clr(state->background), SCALE(100.f));
|
||||
draw->add_circle_filled(window->DrawList, { rect.Min.x + SCALE(state->circle_offset), rect.GetCenter().y }, SCALE(6.f), gui->get_clr(state->circle), SCALE(100.f));
|
||||
|
||||
draw->render_text(window->DrawList, set->c_font.inter_medium[0], clickable_rect.Min, clickable_rect.Max, gui->get_clr(state->text_colored), label.data(), NULL, NULL, { 0.0, 0.5 });
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool c_widget::checkbox_with_key(std::string_view label, bool* callback, int* key, bool* mode, bool* value, bool* show_in_binds)
|
||||
{
|
||||
struct c_checkbox
|
||||
{
|
||||
ImVec4 background = clr->c_element.layout;
|
||||
|
||||
ImVec4 text_colored = clr->c_text.text;
|
||||
ImVec4 circle = clr->c_element.circle;
|
||||
|
||||
float circle_offset = 0;
|
||||
};
|
||||
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label.data());
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label.data(), NULL, true);
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
|
||||
const float w = GetContentRegionAvail().x;
|
||||
const float h = SCALE(30);
|
||||
|
||||
const ImRect clickable_rect(pos, pos + ImVec2(w, h));
|
||||
const ImRect rect(pos + ImVec2(w - SCALE(40), SCALE(4)), pos + ImVec2(w, h - SCALE(4)));
|
||||
|
||||
ItemSize(clickable_rect, 0.f);
|
||||
if (!ItemAdd(clickable_rect, id)) return false;
|
||||
|
||||
bool hovered, held, pressed = ButtonBehavior(clickable_rect, id, &hovered, &held);
|
||||
|
||||
c_checkbox* state = gui->anim_container(&state, id);
|
||||
state->text_colored = ImLerp(state->text_colored, *callback ? clr->c_text.text_active : hovered ? clr->c_text.text_hov : clr->c_text.text, ImGui::GetIO().DeltaTime * 8.f);
|
||||
state->background = ImLerp(state->background, *callback ? clr->c_element.checkbox_active : clr->c_element.layout, ImGui::GetIO().DeltaTime * 8.f);
|
||||
|
||||
state->circle = ImLerp(state->circle, *callback ? clr->c_other_clr.accent_clr : clr->c_element.circle, ImGui::GetIO().DeltaTime * 8.f);
|
||||
state->circle_offset = ImLerp(state->circle_offset, *callback ? 28.f : 12.f, gui->fixed_speed(30.f));
|
||||
|
||||
widget->begin_popup((std::stringstream{} << id << "keybind").str().c_str(), 170, {w - SCALE(92), SCALE(-40)});
|
||||
{
|
||||
|
||||
widget->keybind("keybind", key);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->keybind_button("mode", mode);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox("Value", value);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox("Show binds", show_in_binds);
|
||||
|
||||
}
|
||||
widget->end_popup();
|
||||
|
||||
if (pressed)
|
||||
{
|
||||
*callback = !(*callback);
|
||||
MarkItemEdited(id);
|
||||
}
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max, gui->get_clr(state->background), SCALE(100.f));
|
||||
draw->add_circle_filled(window->DrawList, { rect.Min.x + SCALE(state->circle_offset), rect.GetCenter().y }, SCALE(6.f), gui->get_clr(state->circle), SCALE(100.f));
|
||||
|
||||
draw->render_text(window->DrawList, set->c_font.icon[1], clickable_rect.Min, clickable_rect.Max - ImVec2(SCALE(60), 0), gui->get_clr(clr->c_element.popup_icon), "E", NULL, NULL, {1.0, 0.5});
|
||||
draw->render_text(window->DrawList, set->c_font.inter_medium[0], clickable_rect.Min, clickable_rect.Max, gui->get_clr(state->text_colored), label.data(), NULL, NULL, { 0.0, 0.5 });
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool c_widget::checkbox_with_color(std::string_view label, bool* callback, float col[4], bool alpha)
|
||||
{
|
||||
struct c_checkbox
|
||||
{
|
||||
ImVec4 background = clr->c_element.layout;
|
||||
|
||||
ImVec4 text_colored = clr->c_text.text;
|
||||
ImVec4 circle = clr->c_element.circle;
|
||||
|
||||
float circle_offset = 0;
|
||||
};
|
||||
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label.data());
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label.data(), NULL, true);
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
|
||||
const float w = GetContentRegionAvail().x;
|
||||
const float h = SCALE(30);
|
||||
|
||||
const ImRect clickable_rect(pos, pos + ImVec2(w, h));
|
||||
const ImRect rect(pos + ImVec2(w - SCALE(40), SCALE(4)), pos + ImVec2(w, h - SCALE(4)));
|
||||
|
||||
ItemSize(clickable_rect, 0.f);
|
||||
if (!ItemAdd(clickable_rect, id)) return false;
|
||||
const ImVec2 stored_pos = GetCursorScreenPos();
|
||||
|
||||
bool hovered, held, pressed = ButtonBehavior(clickable_rect, id, &hovered, &held);
|
||||
|
||||
c_checkbox* state = gui->anim_container(&state, id);
|
||||
state->text_colored = ImLerp(state->text_colored, *callback ? clr->c_text.text_active : hovered ? clr->c_text.text_hov : clr->c_text.text, ImGui::GetIO().DeltaTime * 8.f);
|
||||
state->background = ImLerp(state->background, *callback ? clr->c_element.checkbox_active : clr->c_element.layout, ImGui::GetIO().DeltaTime * 8.f);
|
||||
|
||||
state->circle = ImLerp(state->circle, *callback ? clr->c_other_clr.accent_clr : clr->c_element.circle, ImGui::GetIO().DeltaTime * 8.f);
|
||||
state->circle_offset = ImLerp(state->circle_offset, *callback ? 28.f : 12.f, gui->fixed_speed(30.f));
|
||||
|
||||
SetCursorScreenPos(clickable_rect.Max - SCALE(78, 24));
|
||||
widget->color_edit((std::stringstream{} << id << "colorpicker").str(), col, alpha ? ImGuiColorEditFlags_AlphaBar : 0);
|
||||
SetCursorScreenPos(stored_pos);
|
||||
|
||||
if (pressed)
|
||||
{
|
||||
*callback = !(*callback);
|
||||
MarkItemEdited(id);
|
||||
}
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max, gui->get_clr(state->background), SCALE(100.f));
|
||||
draw->add_circle_filled(window->DrawList, { rect.Min.x + SCALE(state->circle_offset), rect.GetCenter().y }, SCALE(6.f), gui->get_clr(state->circle), SCALE(100.f));
|
||||
|
||||
draw->render_text(window->DrawList, set->c_font.inter_medium[0], clickable_rect.Min, clickable_rect.Max, gui->get_clr(state->text_colored), label.data(), NULL, NULL, { 0.0, 0.5 });
|
||||
|
||||
return pressed;
|
||||
}
|
||||
@@ -0,0 +1,527 @@
|
||||
#include "../settings/functions.h"
|
||||
|
||||
void render_color_rect_with_alpha_checkboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 col, float grid_step, ImVec2 grid_off, float rounding, ImDrawFlags flags)
|
||||
{
|
||||
if ((flags & ImDrawFlags_RoundCornersMask_) == 0)
|
||||
flags = ImDrawFlags_RoundCornersDefault_;
|
||||
if (((col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT) < 0xFF)
|
||||
{
|
||||
ImU32 col_bg1 = GetColorU32(ImAlphaBlendColors(IM_COL32(34, 32, 40, 255), col));
|
||||
ImU32 col_bg2 = GetColorU32(ImAlphaBlendColors(IM_COL32(10, 7, 19, 255), col));
|
||||
draw_list->AddRectFilled(p_min, p_max, col_bg1, rounding, flags);
|
||||
|
||||
int yi = 0;
|
||||
for (float y = p_min.y + grid_off.y; y < p_max.y; y += grid_step, yi++)
|
||||
{
|
||||
float y1 = ImClamp(y, p_min.y, p_max.y), y2 = ImMin(y + grid_step, p_max.y);
|
||||
if (y2 <= y1)
|
||||
continue;
|
||||
for (float x = p_min.x + grid_off.x + (yi & 1) * grid_step; x < p_max.x; x += grid_step * 2.0f)
|
||||
{
|
||||
float x1 = ImClamp(x, p_min.x, p_max.x), x2 = ImMin(x + grid_step, p_max.x);
|
||||
if (x2 <= x1)
|
||||
continue;
|
||||
ImDrawFlags cell_flags = ImDrawFlags_RoundCornersNone;
|
||||
if (y1 <= p_min.y) { if (x1 <= p_min.x) cell_flags |= ImDrawFlags_RoundCornersTopLeft; if (x2 >= p_max.x) cell_flags |= ImDrawFlags_RoundCornersTopRight; }
|
||||
if (y2 >= p_max.y) { if (x1 <= p_min.x) cell_flags |= ImDrawFlags_RoundCornersBottomLeft; if (x2 >= p_max.x) cell_flags |= ImDrawFlags_RoundCornersBottomRight; }
|
||||
|
||||
// Combine flags
|
||||
cell_flags = (flags == ImDrawFlags_RoundCornersNone || cell_flags == ImDrawFlags_RoundCornersNone) ? ImDrawFlags_RoundCornersNone : (cell_flags & flags);
|
||||
draw_list->AddRectFilled(ImVec2(x1, y1), ImVec2(x2, y2), col_bg2, rounding, cell_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
draw_list->AddRectFilled(p_min, p_max, col, rounding, flags);
|
||||
}
|
||||
}
|
||||
|
||||
bool color_button(const char* desc_id, const ImVec4& col, bool opened)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiID id = window->GetID((std::stringstream{} << desc_id << "color_button").str().c_str());
|
||||
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
const ImRect rect(pos, pos + SCALE(20, 20));
|
||||
ItemSize(rect, 0.0f);
|
||||
if (!ItemAdd(rect, id))
|
||||
return false;
|
||||
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(rect, id, &hovered, &held);
|
||||
|
||||
draw->render_text(window->DrawList, set->c_font.icon[1], rect.Min, rect.Max, gui->get_clr(col), "D", NULL, NULL, ImVec2(0.5f, 0.5f));
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
static void color_edit_restore_h(const float* col, float* H)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(g.ColorEditCurrentID != 0);
|
||||
if (g.ColorEditSavedID != g.ColorEditCurrentID || g.ColorEditSavedColor != ImGui::ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 0)))
|
||||
return;
|
||||
*H = g.ColorEditSavedHue;
|
||||
}
|
||||
|
||||
static void color_edit_restore_hs(const float* col, float* H, float* S, float* V)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(g.ColorEditCurrentID != 0);
|
||||
if (g.ColorEditSavedID != g.ColorEditCurrentID || g.ColorEditSavedColor != ImGui::ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 0)))
|
||||
return;
|
||||
|
||||
// When S == 0, H is undefined.
|
||||
// When H == 1 it wraps around to 0.
|
||||
if (*S == 0.0f || (*H == 0.0f && g.ColorEditSavedHue == 1))
|
||||
*H = g.ColorEditSavedHue;
|
||||
|
||||
// When V == 0, S is undefined.
|
||||
if (*V == 0.0f)
|
||||
*S = g.ColorEditSavedSat;
|
||||
}
|
||||
|
||||
ImVec4 imu32_to_imvec4(ImU32 color)
|
||||
{
|
||||
float r = ((color >> 0) & 0xFF) / 255.0f;
|
||||
float g = ((color >> 8) & 0xFF) / 255.0f;
|
||||
float b = ((color >> 16) & 0xFF) / 255.0f;
|
||||
float a = ((color >> 24) & 0xFF) / 255.0f;
|
||||
return ImVec4(r, g, b, a);
|
||||
}
|
||||
|
||||
bool color_picker(const char* label, float col[4], ImGuiColorEditFlags flags, const float* ref_col)
|
||||
{
|
||||
struct picker_state
|
||||
{
|
||||
float lerp[2] = { 0, 0 };
|
||||
};
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
ImDrawList* draw_list = window->DrawList;
|
||||
ImGuiStyle& style = g.Style;
|
||||
ImGuiIO& io = g.IO;
|
||||
|
||||
const float width = CalcItemWidth();
|
||||
const bool is_readonly = ((g.NextItemData.ItemFlags | g.CurrentItemFlags) & ImGuiItemFlags_ReadOnly) != 0;
|
||||
g.NextItemData.ClearFlags();
|
||||
|
||||
PushID(label);
|
||||
const bool set_current_color_edit_id = (g.ColorEditCurrentID == 0);
|
||||
if (set_current_color_edit_id)
|
||||
g.ColorEditCurrentID = window->IDStack.back();
|
||||
BeginGroup();
|
||||
|
||||
if (!(flags & ImGuiColorEditFlags_NoSidePreview))
|
||||
flags |= ImGuiColorEditFlags_NoSmallPreview;
|
||||
|
||||
// Context menu: display and store options.
|
||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||
ColorPickerOptionsPopup(col, flags);
|
||||
|
||||
// Read stored options
|
||||
if (!(flags & ImGuiColorEditFlags_PickerMask_))
|
||||
flags |= ((g.ColorEditOptions & ImGuiColorEditFlags_PickerMask_) ? g.ColorEditOptions : ImGuiColorEditFlags_DefaultOptions_) & ImGuiColorEditFlags_PickerMask_;
|
||||
if (!(flags & ImGuiColorEditFlags_InputMask_))
|
||||
flags |= ((g.ColorEditOptions & ImGuiColorEditFlags_InputMask_) ? g.ColorEditOptions : ImGuiColorEditFlags_DefaultOptions_) & ImGuiColorEditFlags_InputMask_;
|
||||
IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags_PickerMask_)); // Check that only 1 is selected
|
||||
IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags_InputMask_)); // Check that only 1 is selected
|
||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||
flags |= (g.ColorEditOptions & ImGuiColorEditFlags_AlphaBar);
|
||||
|
||||
// Setup
|
||||
int components = (flags & ImGuiColorEditFlags_NoAlpha) ? 3 : 4;
|
||||
bool alpha_bar = (flags & ImGuiColorEditFlags_AlphaBar) && !(flags & ImGuiColorEditFlags_NoAlpha);
|
||||
ImVec2 picker_pos = window->DC.CursorPos;
|
||||
|
||||
ImVec2 hue_bar_pos = picker_pos + ImVec2(0, SCALE(set->c_picker.picker_size.y) + SCALE(set->c_picker.padding.x));
|
||||
ImVec2 alpha_bar_pos = hue_bar_pos + ImVec2(0, SCALE(set->c_picker.bar_size.y) + SCALE(set->c_picker.padding.x));
|
||||
|
||||
float backup_initial_col[4];
|
||||
memcpy(backup_initial_col, col, components * sizeof(float));
|
||||
|
||||
float H = col[0], S = col[1], V = col[2];
|
||||
float R = col[0], G = col[1], B = col[2];
|
||||
|
||||
if (flags & ImGuiColorEditFlags_InputRGB)
|
||||
{
|
||||
// Hue is lost when converting from grayscale rgb (saturation=0). Restore it.
|
||||
ColorConvertRGBtoHSV(R, G, B, H, S, V);
|
||||
color_edit_restore_hs(col, &H, &S, &V);
|
||||
}
|
||||
else if (flags & ImGuiColorEditFlags_InputHSV)
|
||||
{
|
||||
ColorConvertHSVtoRGB(H, S, V, R, G, B);
|
||||
}
|
||||
|
||||
picker_state* animstate = gui->anim_container(&animstate, GetID((std::stringstream{} << GetCurrentWindow()->ID << "saved_pos").str().c_str()));
|
||||
|
||||
bool value_changed = false, value_changed_h = false, value_changed_sv = false;
|
||||
PushItemFlag(ImGuiItemFlags_NoNav, true);
|
||||
// SV rectangle logic
|
||||
InvisibleButton("sv", SCALE(set->c_picker.picker_size));
|
||||
if (IsItemActive() && !is_readonly)
|
||||
{
|
||||
S = ImSaturate((io.MousePos.x - picker_pos.x) / (SCALE(set->c_picker.picker_size.x) - 1));
|
||||
V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (SCALE(set->c_picker.picker_size.y) - 1));
|
||||
color_edit_restore_h(col, &H); // Greatly reduces hue jitter and reset to 0 when hue == 255 and color is rapidly modified using SV square.
|
||||
value_changed = value_changed_sv = true;
|
||||
}
|
||||
|
||||
// Hue bar logic
|
||||
SetCursorScreenPos(hue_bar_pos);
|
||||
InvisibleButton("hue", SCALE(set->c_picker.bar_size));
|
||||
if (IsItemActive() && !is_readonly)
|
||||
{
|
||||
H = 1.0f - ImSaturate((io.MousePos.x - picker_pos.x) / (SCALE(set->c_picker.bar_size.x) - 1));
|
||||
value_changed = value_changed_h = true;
|
||||
}
|
||||
|
||||
// Alpha bar logic
|
||||
if (alpha_bar)
|
||||
{
|
||||
SetCursorScreenPos(alpha_bar_pos);
|
||||
InvisibleButton("alpha", SCALE(set->c_picker.bar_size));
|
||||
if (IsItemActive())
|
||||
{
|
||||
col[3] = ImSaturate((io.MousePos.x - picker_pos.x) / (SCALE(set->c_picker.bar_size.x) - 1));
|
||||
value_changed = true;
|
||||
}
|
||||
}
|
||||
PopItemFlag(); // ImGuiItemFlags_NoNav
|
||||
|
||||
// Convert back color to RGB
|
||||
if (value_changed_h || value_changed_sv)
|
||||
{
|
||||
if (flags & ImGuiColorEditFlags_InputRGB)
|
||||
{
|
||||
ColorConvertHSVtoRGB(H, S, V, col[0], col[1], col[2]);
|
||||
g.ColorEditSavedHue = H;
|
||||
g.ColorEditSavedSat = S;
|
||||
g.ColorEditSavedID = g.ColorEditCurrentID;
|
||||
g.ColorEditSavedColor = ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 0));
|
||||
}
|
||||
else if (flags & ImGuiColorEditFlags_InputHSV)
|
||||
{
|
||||
col[0] = H;
|
||||
col[1] = S;
|
||||
col[2] = V;
|
||||
}
|
||||
}
|
||||
|
||||
// R,G,B and H,S,V slider color editor
|
||||
bool value_changed_fix_hue_wrap = false;
|
||||
|
||||
// Try to cancel hue wrap (after ColorEdit4 call), if any
|
||||
if (value_changed_fix_hue_wrap && (flags & ImGuiColorEditFlags_InputRGB))
|
||||
{
|
||||
float new_H, new_S, new_V;
|
||||
ColorConvertRGBtoHSV(col[0], col[1], col[2], new_H, new_S, new_V);
|
||||
if (new_H <= 0 && H > 0)
|
||||
{
|
||||
if (new_V <= 0 && V != new_V)
|
||||
ColorConvertHSVtoRGB(H, S, new_V <= 0 ? V * 0.5f : new_V, col[0], col[1], col[2]);
|
||||
else if (new_S <= 0)
|
||||
ColorConvertHSVtoRGB(H, new_S <= 0 ? S * 0.5f : new_S, new_V, col[0], col[1], col[2]);
|
||||
}
|
||||
}
|
||||
|
||||
if (value_changed)
|
||||
{
|
||||
if (flags & ImGuiColorEditFlags_InputRGB)
|
||||
{
|
||||
R = col[0];
|
||||
G = col[1];
|
||||
B = col[2];
|
||||
ColorConvertRGBtoHSV(R, G, B, H, S, V);
|
||||
color_edit_restore_hs(col, &H, &S, &V); // Fix local Hue as display below will use it immediately.
|
||||
}
|
||||
else if (flags & ImGuiColorEditFlags_InputHSV)
|
||||
{
|
||||
H = col[0];
|
||||
S = col[1];
|
||||
V = col[2];
|
||||
ColorConvertHSVtoRGB(H, S, V, R, G, B);
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & ImGuiColorEditFlags_NoInputs) == 0)
|
||||
{
|
||||
ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf;
|
||||
ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker;
|
||||
if (flags & ImGuiColorEditFlags_DisplayHex || (flags & ImGuiColorEditFlags_DisplayMask_) == 0)
|
||||
{
|
||||
SetCursorPosY(GetCursorPosY() + SCALE(10));
|
||||
value_changed |= widget->color_edit("##hex", col, sub_flags | ImGuiColorEditFlags_DisplayHex);
|
||||
}
|
||||
}
|
||||
|
||||
const int style_alpha8 = IM_F32_TO_INT8_SAT(style.Alpha);
|
||||
const ImU32 col_black = IM_COL32(0, 0, 0, style_alpha8);
|
||||
const ImU32 col_white = IM_COL32(255, 255, 255, style_alpha8);
|
||||
const ImU32 col_midgrey = IM_COL32(128, 128, 128, style_alpha8);
|
||||
const ImU32 col_hues[6 + 1] = {
|
||||
IM_COL32(255,0,0,style_alpha8), // 7
|
||||
IM_COL32(255,0,255,style_alpha8), // 6
|
||||
IM_COL32(0,0,255,style_alpha8), // 5
|
||||
IM_COL32(0,255,255,style_alpha8), // 4
|
||||
IM_COL32(0,255,0,style_alpha8), // 3
|
||||
IM_COL32(255,255,0,style_alpha8), // 2
|
||||
IM_COL32(255,0,0,style_alpha8) // 1
|
||||
};
|
||||
|
||||
ImVec4 hue_color_f(1, 1, 1, style.Alpha); ColorConvertHSVtoRGB(H, 1, 1, hue_color_f.x, hue_color_f.y, hue_color_f.z);
|
||||
ImU32 hue_color32 = ColorConvertFloat4ToU32(hue_color_f);
|
||||
ImU32 user_col32_striped_of_alpha = ColorConvertFloat4ToU32(ImVec4(R, G, B, style.Alpha)); // Important: this is still including the main rendering/style alpha!!
|
||||
|
||||
ImVec2 sv_cursor_pos;
|
||||
|
||||
// Render SV Square
|
||||
draw->rect_filled_multi_color(draw_list, picker_pos, picker_pos + SCALE(set->c_picker.picker_size), col_white, hue_color32, hue_color32, col_white, SCALE(set->c_picker.rounding + 1));
|
||||
draw->rect_filled_multi_color(draw_list, picker_pos, picker_pos + SCALE(set->c_picker.picker_size) + SCALE(0, 1), 0, 0, col_black, col_black, SCALE(set->c_picker.rounding));
|
||||
|
||||
sv_cursor_pos.x = ImClamp(IM_ROUND(picker_pos.x + ImSaturate(S) * SCALE(set->c_picker.picker_size.x)), picker_pos.x + 2, picker_pos.x + SCALE(set->c_picker.picker_size.x) - 2); // Sneakily prevent the circle to stick out too much
|
||||
sv_cursor_pos.y = ImClamp(IM_ROUND(picker_pos.y + ImSaturate(1 - V) * SCALE(set->c_picker.picker_size.y)), picker_pos.y + 2, picker_pos.y + SCALE(set->c_picker.picker_size.y) - 2);
|
||||
|
||||
// Render Hue Bar
|
||||
for (int i = 0; i < 6; ++i)
|
||||
draw->rect_filled_multi_color(draw_list, hue_bar_pos + ImVec2(i * (SCALE(set->c_picker.bar_size.x) / 6) - (i == 5 ? 1 : 0), 0), hue_bar_pos + ImVec2((i + 1) * (SCALE(set->c_picker.bar_size.x) / 6) + (i == 0 ? 1 : 0), SCALE(set->c_picker.bar_size.y)), col_hues[i], col_hues[i + 1], col_hues[i + 1], col_hues[i], SCALE(set->c_element.rounding), i == 0 ? ImDrawFlags_RoundCornersLeft : i == 5 ? ImDrawFlags_RoundCornersRight : ImDrawFlags_RoundCornersNone);
|
||||
|
||||
float hue_bar_circle_pos = IM_ROUND((1.0f - H) * SCALE(set->c_picker.bar_size.x));
|
||||
hue_bar_circle_pos = ImClamp(hue_bar_circle_pos, 4.f, SCALE(set->c_picker.bar_size.x) - 5.f);
|
||||
animstate->lerp[0] = ImLerp(animstate->lerp[0], hue_bar_circle_pos, gui->fixed_speed(20.f));
|
||||
draw_list->AddCircle(hue_bar_pos + ImVec2(animstate->lerp[0], SCALE(set->c_picker.bar_size.y) / 2), SCALE(set->c_picker.bar_size.y) / 2, col_white, 30, SCALE(1.f));
|
||||
|
||||
// Render cursor/preview circle (clamp S/V within 0..1 range because floating points colors may lead HSV values to be out of range)
|
||||
draw_list->AddCircleFilled(sv_cursor_pos, SCALE(set->c_picker.bar_size.y) / 2, user_col32_striped_of_alpha, 20);
|
||||
draw_list->AddCircle(sv_cursor_pos, SCALE(set->c_picker.bar_size.y) / 2, col_white, 20, SCALE(1.f));
|
||||
|
||||
// Render alpha bar
|
||||
if (alpha_bar)
|
||||
{
|
||||
float alpha = ImSaturate(col[3]);
|
||||
render_color_rect_with_alpha_checkboard(draw_list, alpha_bar_pos, alpha_bar_pos + SCALE(set->c_picker.bar_size), ImColor(0, 0, 0, 0), SCALE(set->c_picker.bar_size.y) / 2, ImVec2(0, 0), SCALE(set->c_element.rounding), 0);
|
||||
draw->rect_filled_multi_color(draw_list, alpha_bar_pos, alpha_bar_pos + SCALE(set->c_picker.bar_size), user_col32_striped_of_alpha & ~IM_COL32_A_MASK, user_col32_striped_of_alpha, user_col32_striped_of_alpha, user_col32_striped_of_alpha & ~IM_COL32_A_MASK, SCALE(set->c_element.rounding));
|
||||
float alpha_bar_circle_pos = IM_ROUND(alpha * SCALE(set->c_picker.bar_size.x));
|
||||
alpha_bar_circle_pos = ImClamp(alpha_bar_circle_pos, 5.f, SCALE(set->c_picker.bar_size.x) - 5.f);
|
||||
animstate->lerp[1] = ImLerp(animstate->lerp[1], alpha_bar_circle_pos, gui->fixed_speed(20.f));
|
||||
draw_list->AddCircle(alpha_bar_pos + ImVec2(animstate->lerp[1], SCALE(set->c_picker.bar_size.y) / 2), SCALE(set->c_picker.bar_size.y) / 2, col_white, 30, SCALE(1.f));
|
||||
}
|
||||
|
||||
EndGroup();
|
||||
|
||||
if (value_changed && memcmp(backup_initial_col, col, components * sizeof(float)) == 0)
|
||||
value_changed = false;
|
||||
if (value_changed && g.LastItemData.ID != 0) // In case of ID collision, the second EndGroup() won't catch g.ActiveId
|
||||
MarkItemEdited(g.LastItemData.ID);
|
||||
|
||||
if (set_current_color_edit_id)
|
||||
g.ColorEditCurrentID = 0;
|
||||
PopID();
|
||||
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
bool c_widget::color_edit(std::string_view label, float col[4], ImGuiColorEditFlags flags)
|
||||
{
|
||||
struct color_state
|
||||
{
|
||||
bool active = false;
|
||||
bool hovered = false;
|
||||
float alpha = 0.f;
|
||||
float saturation = 4;
|
||||
ImU32 hue_col;
|
||||
};
|
||||
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const float square_sz = GetFrameHeight();
|
||||
const char* label_display_end = FindRenderedTextEnd(label.data());
|
||||
float w_full = CalcItemWidth();
|
||||
g.NextItemData.ClearFlags();
|
||||
|
||||
BeginGroup();
|
||||
PushID(label.data());
|
||||
const bool set_current_color_edit_id = (g.ColorEditCurrentID == 0);
|
||||
if (set_current_color_edit_id)
|
||||
g.ColorEditCurrentID = window->IDStack.back();
|
||||
|
||||
// If we're not showing any slider there's no point in doing any HSV conversions
|
||||
const ImGuiColorEditFlags flags_untouched = flags;
|
||||
if (flags & ImGuiColorEditFlags_NoInputs)
|
||||
flags = (flags & (~ImGuiColorEditFlags_DisplayMask_)) | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_NoOptions;
|
||||
|
||||
// Context menu: display and modify options (before defaults are applied)
|
||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||
ColorEditOptionsPopup(col, flags);
|
||||
|
||||
// Read stored options
|
||||
if (!(flags & ImGuiColorEditFlags_DisplayMask_))
|
||||
flags |= (g.ColorEditOptions & ImGuiColorEditFlags_DisplayMask_);
|
||||
if (!(flags & ImGuiColorEditFlags_DataTypeMask_))
|
||||
flags |= (g.ColorEditOptions & ImGuiColorEditFlags_DataTypeMask_);
|
||||
if (!(flags & ImGuiColorEditFlags_PickerMask_))
|
||||
flags |= (g.ColorEditOptions & ImGuiColorEditFlags_PickerMask_);
|
||||
if (!(flags & ImGuiColorEditFlags_InputMask_))
|
||||
flags |= (g.ColorEditOptions & ImGuiColorEditFlags_InputMask_);
|
||||
flags |= (g.ColorEditOptions & ~(ImGuiColorEditFlags_DisplayMask_ | ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_PickerMask_ | ImGuiColorEditFlags_InputMask_));
|
||||
IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags_DisplayMask_)); // Check that only 1 is selected
|
||||
IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags_InputMask_)); // Check that only 1 is selected
|
||||
|
||||
const bool alpha = (flags & ImGuiColorEditFlags_NoAlpha) == 0;
|
||||
const bool hdr = (flags & ImGuiColorEditFlags_HDR) != 0;
|
||||
const int components = alpha ? 4 : 3;
|
||||
const float w_button = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (square_sz + style.ItemInnerSpacing.x);
|
||||
const float w_inputs = ImMax(w_full - w_button, 1.0f);
|
||||
w_full = w_inputs + w_button;
|
||||
|
||||
// Convert to the formats we need
|
||||
float f[4] = { col[0], col[1], col[2], alpha ? col[3] : 1.0f };
|
||||
if ((flags & ImGuiColorEditFlags_InputHSV) && (flags & ImGuiColorEditFlags_DisplayRGB))
|
||||
ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]);
|
||||
else if ((flags & ImGuiColorEditFlags_InputRGB) && (flags & ImGuiColorEditFlags_DisplayHSV))
|
||||
{
|
||||
// Hue is lost when converting from grayscale rgb (saturation=0). Restore it.
|
||||
ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]);
|
||||
color_edit_restore_hs(col, &f[0], &f[1], &f[2]);
|
||||
}
|
||||
int i[4] = { IM_F32_TO_INT8_UNBOUND(f[0]), IM_F32_TO_INT8_UNBOUND(f[1]), IM_F32_TO_INT8_UNBOUND(f[2]), IM_F32_TO_INT8_UNBOUND(f[3]) };
|
||||
|
||||
bool value_changed = false;
|
||||
bool value_changed_as_float = false;
|
||||
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
const float inputs_offset_x = (style.ColorButtonPosition == ImGuiDir_Left) ? w_button : 0.0f;
|
||||
|
||||
color_state* state = gui->anim_container(&state, GetID(label.data()));
|
||||
|
||||
if ((flags & ImGuiColorEditFlags_DisplayHex) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0)
|
||||
{
|
||||
// RGB Hexadecimal Input
|
||||
char buf[64];
|
||||
if (alpha)
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255), ImClamp(i[3], 0, 255));
|
||||
else
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255));
|
||||
SetNextItemWidth(w_inputs);
|
||||
gui->set_cursor_pos_y(gui->get_cursor_pos_y() - SCALE(11));
|
||||
if (widget->text_field("##Text", "M", buf, IM_ARRAYSIZE(buf), SCALE(150, 30), ImGuiInputTextFlags_CharsUppercase))
|
||||
{
|
||||
value_changed = true;
|
||||
char* p = buf;
|
||||
while (*p == '#' || ImCharIsBlankA(*p))
|
||||
p++;
|
||||
i[0] = i[1] = i[2] = 0;
|
||||
i[3] = 0xFF; // alpha default to 255 is not parsed by scanf (e.g. inputting #FFFFFF omitting alpha)
|
||||
int r;
|
||||
if (alpha)
|
||||
r = sscanf(p, "%02X%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2], (unsigned int*)&i[3]); // Treat at unsigned (%X is unsigned)
|
||||
else
|
||||
r = sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]);
|
||||
IM_UNUSED(r); // Fixes C6031: Return value ignored: 'sscanf'.
|
||||
}
|
||||
}
|
||||
|
||||
if (g.LastItemData.Rect.Contains(g.IO.MousePos) && g.IO.MouseClicked[1] || (state->active && (g.IO.MouseClicked[0] || g.IO.MouseClicked[1]) && !state->hovered))
|
||||
state->active = !state->active;
|
||||
|
||||
ImGuiWindow* picker_active_window = NULL;
|
||||
if (!(flags & ImGuiColorEditFlags_NoSmallPreview))
|
||||
{
|
||||
const ImVec4 col_v4(col[0], col[1], col[2], alpha ? col[3] : 1.0f);
|
||||
if (color_button(label.data(), col_v4, state->active))
|
||||
g.ColorPickerRef = col_v4;
|
||||
|
||||
state->alpha = ImClamp(state->alpha + (8.f * g.IO.DeltaTime * (state->active ? 1.f : -1.f)), 0.f, 1.f);
|
||||
|
||||
if (!IsRectVisible(g.LastItemData.Rect.Min, g.LastItemData.Rect.Max + ImVec2(0, 2)))
|
||||
{
|
||||
state->active = false;
|
||||
state->alpha = 0.f;
|
||||
}
|
||||
|
||||
//SetNextWindowSize(SCALE(170, flags & ImGuiColorEditFlags_AlphaBar ? 272 : 254));
|
||||
SetNextWindowPos(g.LastItemData.Rect.GetTL());
|
||||
gui->push_style_var(ImGuiStyleVar_Alpha, state->alpha);
|
||||
gui->push_style_var(ImGuiStyleVar_WindowBorderSize, 1.f);
|
||||
gui->push_style_var(ImGuiStyleVar_WindowRounding, SCALE(set->c_child.rounding));
|
||||
|
||||
gui->push_style_color(ImGuiCol_PopupBg, gui->get_clr(clr->c_child.layout));
|
||||
gui->push_style_color(ImGuiCol_Border, gui->get_clr(clr->c_child.stroke));
|
||||
|
||||
if (state->alpha >= 0.01f);
|
||||
{
|
||||
gui->begin((std::stringstream{} << "picker_window" << GetID(label.data())).str(), NULL, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_AlwaysAutoResize);
|
||||
{
|
||||
if (state->active)
|
||||
SetWindowFocus();
|
||||
state->hovered = IsWindowHovered();
|
||||
picker_active_window = g.CurrentWindow;
|
||||
|
||||
ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_PickerMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar;
|
||||
ImGuiColorEditFlags picker_flags = (flags_untouched & picker_flags_to_forward) | ImGuiColorEditFlags_DisplayMask_ | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_AlphaPreviewHalf;
|
||||
|
||||
gui->begin_group();
|
||||
|
||||
value_changed |= color_picker("##picker", col, picker_flags, &g.ColorPickerRef.x);
|
||||
|
||||
gui->end_group();
|
||||
|
||||
}
|
||||
gui->end();
|
||||
}
|
||||
gui->pop_style_var(3);
|
||||
gui->pop_style_color(2);
|
||||
}
|
||||
|
||||
// Convert back
|
||||
if (value_changed && picker_active_window == NULL)
|
||||
{
|
||||
if (!value_changed_as_float)
|
||||
for (int n = 0; n < 4; n++)
|
||||
f[n] = i[n] / 255.0f;
|
||||
if ((flags & ImGuiColorEditFlags_DisplayHSV) && (flags & ImGuiColorEditFlags_InputRGB))
|
||||
{
|
||||
g.ColorEditSavedHue = f[0];
|
||||
g.ColorEditSavedSat = f[1];
|
||||
ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]);
|
||||
g.ColorEditSavedID = g.ColorEditCurrentID;
|
||||
g.ColorEditSavedColor = ColorConvertFloat4ToU32(ImVec4(f[0], f[1], f[2], 0));
|
||||
}
|
||||
if ((flags & ImGuiColorEditFlags_DisplayRGB) && (flags & ImGuiColorEditFlags_InputHSV))
|
||||
ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]);
|
||||
|
||||
col[0] = f[0];
|
||||
col[1] = f[1];
|
||||
col[2] = f[2];
|
||||
if (alpha)
|
||||
col[3] = f[3];
|
||||
}
|
||||
|
||||
if (set_current_color_edit_id)
|
||||
g.ColorEditCurrentID = 0;
|
||||
PopID();
|
||||
EndGroup();
|
||||
|
||||
// When picker is being actively used, use its active id so IsItemActive() will function on ColorEdit4().
|
||||
if (picker_active_window && g.ActiveId != 0 && g.ActiveIdWindow == picker_active_window)
|
||||
g.LastItemData.ID = g.ActiveId;
|
||||
|
||||
if (value_changed && g.LastItemData.ID != 0) // In case of ID collision, the second EndGroup() won't catch g.ActiveId
|
||||
MarkItemEdited(g.LastItemData.ID);
|
||||
|
||||
return value_changed;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#include "../settings/functions.h"
|
||||
|
||||
bool active_button(std::string_view label, int selection_id, int& selection_variable) {
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label.data());
|
||||
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
ImRect rect(pos, pos + SCALE(100, 40));
|
||||
|
||||
ItemSize(rect, 0);
|
||||
if (!ItemAdd(rect, id)) return false;
|
||||
|
||||
const bool selected = selection_id == selection_variable;
|
||||
bool hovered, held, pressed = ButtonBehavior(rect, id, &hovered, &held);
|
||||
if (pressed) selection_variable = selection_id;
|
||||
|
||||
float* state = gui->anim_container(&state, id);
|
||||
*state = ImClamp(*state + (gui->fixed_speed(8.f) * (!selected ? 1.f : -1.f)), 0.f, 1.f);
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max, gui->get_clr(clr->c_lua.stroke), SCALE(2.f));
|
||||
draw->render_text(window->DrawList, set->c_font.inter_medium[1], rect.Min, rect.Max, gui->get_clr(clr->c_text.text), "LOADED", NULL, NULL, ImVec2(0.5f, 0.5f));
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max, gui->get_clr(clr->c_other_clr.accent_clr, *state), SCALE(2.f));
|
||||
draw->render_text(window->DrawList, set->c_font.inter_medium[1], rect.Min, rect.Max, gui->get_clr(clr->c_text.text_active, *state), "LOAD", NULL, NULL, ImVec2(0.5f, 0.5f));
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool c_widget::config_selectable(config_data* data, int selection_id, int& selection_variable)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems) return false;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID((std::stringstream{} << data->name << selection_id).str().c_str());
|
||||
|
||||
const bool selected = selection_id == selection_variable;
|
||||
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
const float width = GetContentRegionAvail().x;
|
||||
ImRect rect(pos, pos + ImVec2(width, SCALE(60)));
|
||||
|
||||
ItemSize(rect, 0);
|
||||
if (!ItemAdd(rect, id)) return false;
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max, gui->get_clr(clr->c_lua.background), SCALE(set->c_child.rounding));
|
||||
draw->add_rect(window->DrawList, rect.Min, rect.Max, gui->get_clr(clr->c_lua.stroke), SCALE(set->c_child.rounding), 0, SCALE(1.f));
|
||||
draw->render_text(window->DrawList, set->c_font.inter_medium[1], rect.Min + SCALE(10, 11), rect.Max, gui->get_clr(clr->c_text.text_active), data->name.data());
|
||||
draw->render_text(window->DrawList, set->c_font.inter_medium[0], rect.Min + SCALE(10, 33), rect.Max, gui->get_clr(clr->c_text.text_active), "Modified:");
|
||||
draw->render_text(window->DrawList, set->c_font.inter_medium[0], rect.Min + SCALE(69, 33), rect.Max, gui->get_clr(clr->c_other_clr.accent_clr), data->date.data());
|
||||
|
||||
const ImVec2 stored_cursor_pos = GetCursorScreenPos();
|
||||
|
||||
SetCursorScreenPos(ImVec2(rect.Max.x - SCALE(110), rect.Min.y + SCALE(10)));
|
||||
active_button((std::stringstream{} << data->name << id).str(), selection_id, selection_variable);
|
||||
|
||||
SetCursorScreenPos(ImVec2(rect.Max.x - SCALE(146), rect.Min.y + SCALE(23)));
|
||||
if (lua_tool_button("C", std::to_string(id)))
|
||||
var->c_config.data.erase(var->c_config.data.begin() + selection_id);
|
||||
|
||||
SetCursorScreenPos(stored_cursor_pos);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,425 @@
|
||||
#include "../settings/functions.h"
|
||||
|
||||
using namespace ImGui;
|
||||
|
||||
static inline ImDrawFlags fix_rect_corner_flag(ImDrawFlags flags)
|
||||
{
|
||||
IM_ASSERT((flags & 0x0F) == 0 && "Misuse of legacy hardcoded ImDrawCornerFlags values!");
|
||||
if ((flags & ImDrawFlags_RoundCornersMask_) == 0) flags |= ImDrawFlags_RoundCornersAll;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
void c_draw::rect_filled_multi_color(ImDrawList* draw, const ImVec2& p_min, const ImVec2& p_max, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left, float rounding, ImDrawFlags flags)
|
||||
{
|
||||
if (((col_upr_left | col_upr_right | col_bot_right | col_bot_left) & IM_COL32_A_MASK) == 0)
|
||||
return;
|
||||
|
||||
auto fix_rect_corner_flags = [](ImDrawFlags rflags)
|
||||
{
|
||||
if ((rflags & ImDrawFlags_RoundCornersMask_) == 0)
|
||||
rflags |= ImDrawFlags_RoundCornersAll;
|
||||
return rflags;
|
||||
};
|
||||
|
||||
flags = fix_rect_corner_flags(flags);
|
||||
rounding = ImMin(rounding, ImFabs(p_max.x - p_min.x) * (((flags & ImDrawFlags_RoundCornersTop) == ImDrawFlags_RoundCornersTop) || ((flags & ImDrawFlags_RoundCornersBottom) == ImDrawFlags_RoundCornersBottom) ? 0.5f : 1.0f) - 1.0f);
|
||||
rounding = ImMin(rounding, ImFabs(p_max.y - p_min.y) * (((flags & ImDrawFlags_RoundCornersLeft) == ImDrawFlags_RoundCornersLeft) || ((flags & ImDrawFlags_RoundCornersRight) == ImDrawFlags_RoundCornersRight) ? 0.5f : 1.0f) - 1.0f);
|
||||
|
||||
if (rounding > 0.0f)
|
||||
{
|
||||
const int size_before = draw->VtxBuffer.Size;
|
||||
draw->AddRectFilled(p_min, p_max, IM_COL32_WHITE, rounding, flags);
|
||||
const int size_after = draw->VtxBuffer.Size;
|
||||
|
||||
for (int i = size_before; i < size_after; i++)
|
||||
{
|
||||
ImDrawVert* vert = draw->VtxBuffer.Data + i;
|
||||
|
||||
ImVec4 upr_left = ImGui::ColorConvertU32ToFloat4(col_upr_left);
|
||||
ImVec4 bot_left = ImGui::ColorConvertU32ToFloat4(col_bot_left);
|
||||
ImVec4 up_right = ImGui::ColorConvertU32ToFloat4(col_upr_right);
|
||||
ImVec4 bot_right = ImGui::ColorConvertU32ToFloat4(col_bot_right);
|
||||
|
||||
float X = ImClamp((vert->pos.x - p_min.x) / (p_max.x - p_min.x), 0.0f, 1.0f);
|
||||
|
||||
// 4 colors - 8 deltas
|
||||
|
||||
float r1 = upr_left.x + (up_right.x - upr_left.x) * X;
|
||||
float r2 = bot_left.x + (bot_right.x - bot_left.x) * X;
|
||||
|
||||
float g1 = upr_left.y + (up_right.y - upr_left.y) * X;
|
||||
float g2 = bot_left.y + (bot_right.y - bot_left.y) * X;
|
||||
|
||||
float b1 = upr_left.z + (up_right.z - upr_left.z) * X;
|
||||
float b2 = bot_left.z + (bot_right.z - bot_left.z) * X;
|
||||
|
||||
float a1 = upr_left.w + (up_right.w - upr_left.w) * X;
|
||||
float a2 = bot_left.w + (bot_right.w - bot_left.w) * X;
|
||||
|
||||
|
||||
float Y = ImClamp((vert->pos.y - p_min.y) / (p_max.y - p_min.y), 0.0f, 1.0f);
|
||||
float r = r1 + (r2 - r1) * Y;
|
||||
float g = g1 + (g2 - g1) * Y;
|
||||
float b = b1 + (b2 - b1) * Y;
|
||||
float a = a1 + (a2 - a1) * Y;
|
||||
ImVec4 RGBA(r, g, b, a);
|
||||
|
||||
RGBA = RGBA * ImGui::ColorConvertU32ToFloat4(vert->col);
|
||||
|
||||
vert->col = ImColor(RGBA);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const ImVec2 uv = draw->_Data->TexUvWhitePixel;
|
||||
draw->PrimReserve(6, 4);
|
||||
draw->PrimWriteIdx((ImDrawIdx)(draw->_VtxCurrentIdx)); draw->PrimWriteIdx((ImDrawIdx)(draw->_VtxCurrentIdx + 1)); draw->PrimWriteIdx((ImDrawIdx)(draw->_VtxCurrentIdx + 2));
|
||||
draw->PrimWriteIdx((ImDrawIdx)(draw->_VtxCurrentIdx)); draw->PrimWriteIdx((ImDrawIdx)(draw->_VtxCurrentIdx + 2)); draw->PrimWriteIdx((ImDrawIdx)(draw->_VtxCurrentIdx + 3));
|
||||
draw->PrimWriteVtx(p_min, uv, col_upr_left);
|
||||
draw->PrimWriteVtx(ImVec2(p_max.x, p_min.y), uv, col_upr_right);
|
||||
draw->PrimWriteVtx(p_max, uv, col_bot_right);
|
||||
draw->PrimWriteVtx(ImVec2(p_min.x, p_max.y), uv, col_bot_left);
|
||||
}
|
||||
|
||||
void set_linear_color(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1)
|
||||
{
|
||||
ImVec2 gradient_extent = gradient_p1 - gradient_p0;
|
||||
float gradient_inv_length2 = 1.0f / ImLengthSqr(gradient_extent);
|
||||
ImDrawVert* vert_start = draw_list->VtxBuffer.Data + vert_start_idx;
|
||||
ImDrawVert* vert_end = draw_list->VtxBuffer.Data + vert_end_idx;
|
||||
const int col0_r = (int)(col0 >> IM_COL32_R_SHIFT) & 0xFF;
|
||||
const int col0_g = (int)(col0 >> IM_COL32_G_SHIFT) & 0xFF;
|
||||
const int col0_b = (int)(col0 >> IM_COL32_B_SHIFT) & 0xFF;
|
||||
const int col_delta_r = ((int)(col1 >> IM_COL32_R_SHIFT) & 0xFF) - col0_r;
|
||||
const int col_delta_g = ((int)(col1 >> IM_COL32_G_SHIFT) & 0xFF) - col0_g;
|
||||
const int col_delta_b = ((int)(col1 >> IM_COL32_B_SHIFT) & 0xFF) - col0_b;
|
||||
for (ImDrawVert* vert = vert_start; vert < vert_end; vert++)
|
||||
{
|
||||
float d = ImDot(vert->pos - gradient_p0, gradient_extent);
|
||||
float t = ImClamp(d * gradient_inv_length2, 0.0f, 1.0f);
|
||||
int r = (int)(col0_r + col_delta_r * t);
|
||||
int g = (int)(col0_g + col_delta_g * t);
|
||||
int b = (int)(col0_b + col_delta_b * t);
|
||||
vert->col = (r << IM_COL32_R_SHIFT) | (g << IM_COL32_G_SHIFT) | (b << IM_COL32_B_SHIFT) | (vert->col & IM_COL32_A_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
void c_draw::fade_rect_filled(ImDrawList* draw, const ImVec2& pos_min, const ImVec2& pos_max, ImU32 col_one, ImU32 col_two, fade_direction direction, float rounding, ImDrawFlags flags)
|
||||
{
|
||||
const ImVec2 fade_pos_in = (direction == fade_direction::diagonally_reversed) ? ImVec2(pos_max.x, pos_min.y) : pos_min;
|
||||
|
||||
const ImVec2 fade_pos_out = (direction == fade_direction::vertically) ? ImVec2(pos_min.x, pos_max.y) :
|
||||
(direction == fade_direction::horizontally) ? ImVec2(pos_max.x, pos_min.y) :
|
||||
(direction == fade_direction::diagonally) ? pos_max :
|
||||
(direction == fade_direction::diagonally_reversed) ? ImVec2(pos_min.x, pos_max.y) : ImVec2(0, 0);
|
||||
|
||||
const int vtx_buffer_start = draw->VtxBuffer.Size;
|
||||
draw->AddRectFilled(pos_min, pos_max, gui->get_clr(ImVec4(1.f, 1.f, 1.f, 1.f)), rounding, flags);
|
||||
const int vtx_buffer_end = draw->VtxBuffer.Size;
|
||||
set_linear_color(draw, vtx_buffer_start, vtx_buffer_end, fade_pos_in, fade_pos_out, col_one, col_two);
|
||||
}
|
||||
|
||||
void c_draw::render_text(ImDrawList* draw_list, ImFont* font, const ImVec2& pos_min, const ImVec2& pos_max, ImU32 color, const char* text, const char* text_display_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect)
|
||||
{
|
||||
gui->push_font(font);
|
||||
|
||||
ImVec2 pos = pos_min;
|
||||
const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_display_end, false, 0.0f);
|
||||
|
||||
const ImVec2* clip_min = clip_rect ? &clip_rect->Min : &pos_min;
|
||||
const ImVec2* clip_max = clip_rect ? &clip_rect->Max : &pos_max;
|
||||
bool need_clipping = (pos.x + text_size.x >= clip_max->x) || (pos.y + text_size.y >= clip_max->y);
|
||||
if (clip_rect) need_clipping |= (pos.x < clip_min->x) || (pos.y < clip_min->y);
|
||||
|
||||
if (align.x > 0.0f) pos.x = ImMax(pos.x, pos.x + (pos_max.x - pos.x - text_size.x) * align.x);
|
||||
if (align.y > 0.0f) pos.y = ImMax(pos.y, pos.y + (pos_max.y - pos.y - text_size.y) * align.y);
|
||||
|
||||
if (need_clipping)
|
||||
{
|
||||
ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y);
|
||||
draw_list->AddText(NULL, 0, pos, color, text, text_display_end, 0.0f, &fine_clip_rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
draw_list->AddText(NULL, 0, pos, color, text, text_display_end, 0.0f, NULL);
|
||||
}
|
||||
gui->pop_font();
|
||||
}
|
||||
|
||||
void c_draw::radial_gradient(ImDrawList* draw_list, const ImVec2& center, float radius, ImU32 col_in, ImU32 col_out)
|
||||
{
|
||||
if (((col_in | col_out) & IM_COL32_A_MASK) == 0 || radius < 0.5f) return;
|
||||
|
||||
draw_list->_PathArcToFastEx(center, radius, 0, IM_DRAWLIST_ARCFAST_SAMPLE_MAX, 0);
|
||||
const int count = draw_list->_Path.Size - 1;
|
||||
|
||||
unsigned int vtx_base = draw_list->_VtxCurrentIdx;
|
||||
draw_list->PrimReserve(count * 3, count + 1);
|
||||
|
||||
const ImVec2 uv = draw_list->_Data->TexUvWhitePixel;
|
||||
draw_list->PrimWriteVtx(center, uv, col_in);
|
||||
for (int n = 0; n < count; n++)
|
||||
draw_list->PrimWriteVtx(draw_list->_Path[n], uv, col_out);
|
||||
|
||||
for (int n = 0; n < count; n++)
|
||||
{
|
||||
draw_list->PrimWriteIdx((ImDrawIdx)(vtx_base));
|
||||
draw_list->PrimWriteIdx((ImDrawIdx)(vtx_base + 1 + n));
|
||||
draw_list->PrimWriteIdx((ImDrawIdx)(vtx_base + 1 + ((n + 1) % count)));
|
||||
}
|
||||
draw_list->_Path.Size = 0;
|
||||
}
|
||||
|
||||
void c_draw::set_linear_color_alpha(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1)
|
||||
{
|
||||
ImVec2 gradient_extent = gradient_p1 - gradient_p0;
|
||||
float gradient_inv_length2 = 1.0f / ImLengthSqr(gradient_extent);
|
||||
ImDrawVert* vert_start = draw_list->VtxBuffer.Data + vert_start_idx;
|
||||
ImDrawVert* vert_end = draw_list->VtxBuffer.Data + vert_end_idx;
|
||||
const int col0_r = (int)(col0 >> IM_COL32_R_SHIFT) & 0xFF;
|
||||
const int col0_g = (int)(col0 >> IM_COL32_G_SHIFT) & 0xFF;
|
||||
const int col0_b = (int)(col0 >> IM_COL32_B_SHIFT) & 0xFF;
|
||||
const int col0_a = (int)(col0 >> IM_COL32_A_SHIFT) & 0xFF;
|
||||
const int col_delta_r = ((int)(col1 >> IM_COL32_R_SHIFT) & 0xFF) - col0_r;
|
||||
const int col_delta_g = ((int)(col1 >> IM_COL32_G_SHIFT) & 0xFF) - col0_g;
|
||||
const int col_delta_b = ((int)(col1 >> IM_COL32_B_SHIFT) & 0xFF) - col0_b;
|
||||
const int col_delta_a = ((int)(col1 >> IM_COL32_A_SHIFT) & 0xFF) - col0_a;
|
||||
for (ImDrawVert* vert = vert_start; vert < vert_end; vert++)
|
||||
{
|
||||
float d = ImDot(vert->pos - gradient_p0, gradient_extent);
|
||||
float t = ImClamp(d * gradient_inv_length2, 0.0f, 1.0f);
|
||||
int r = (int)(col0_r + col_delta_r * t);
|
||||
int g = (int)(col0_g + col_delta_g * t);
|
||||
int b = (int)(col0_b + col_delta_b * t);
|
||||
int a = (int)(col0_a + col_delta_a * t);
|
||||
vert->col = (r << IM_COL32_R_SHIFT) | (g << IM_COL32_G_SHIFT) | (b << IM_COL32_B_SHIFT) | (a << IM_COL32_A_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
void c_draw::add_rect_filled(ImDrawList* draw_list, const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags)
|
||||
{
|
||||
if ((col & IM_COL32_A_MASK) == 0) return;
|
||||
|
||||
if (rounding < 0.5f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone)
|
||||
{
|
||||
draw_list->PrimReserve(6, 4);
|
||||
draw_list->PrimRect(p_min, p_max, col);
|
||||
}
|
||||
else
|
||||
{
|
||||
draw_list->PathRect(p_min, p_max, rounding, flags);
|
||||
draw_list->PathFillConvex(col);
|
||||
}
|
||||
}
|
||||
|
||||
void c_draw::add_rect(ImDrawList* draw_list, const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags, float thickness)
|
||||
{
|
||||
if ((col & IM_COL32_A_MASK) == 0) return;
|
||||
if (draw_list->Flags & ImDrawListFlags_AntiAliasedLines) draw_list->PathRect(p_min + ImVec2(0.50f, 0.50f), p_max - ImVec2(0.50f, 0.50f), rounding, flags);
|
||||
else draw_list->PathRect(p_min + ImVec2(0.50f, 0.50f), p_max - ImVec2(0.49f, 0.49f), rounding, flags);
|
||||
|
||||
draw_list->PathStroke(col, ImDrawFlags_Closed, thickness);
|
||||
}
|
||||
|
||||
void c_draw::add_circle_filled(ImDrawList* draw_list, const ImVec2& center, float radius, ImU32 col, int num_segments)
|
||||
{
|
||||
if ((col & IM_COL32_A_MASK) == 0 || radius < 0.5f) return;
|
||||
|
||||
if (num_segments <= 0)
|
||||
{
|
||||
draw_list->_PathArcToFastEx(center, radius, 0, IM_DRAWLIST_ARCFAST_SAMPLE_MAX, 0);
|
||||
draw_list->_Path.Size--;
|
||||
}
|
||||
else
|
||||
{
|
||||
num_segments = ImClamp(num_segments, 3, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX);
|
||||
|
||||
const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
|
||||
draw_list->PathArcTo(center, radius, 0.0f, a_max, num_segments - 1);
|
||||
}
|
||||
|
||||
draw_list->PathFillConvex(col);
|
||||
}
|
||||
|
||||
void c_draw::add_circle(ImDrawList* draw_list, const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness)
|
||||
{
|
||||
if ((col & IM_COL32_A_MASK) == 0 || radius < 0.5f) return;
|
||||
|
||||
if (num_segments <= 0)
|
||||
{
|
||||
draw_list->_PathArcToFastEx(center, radius - 0.5f, 0, IM_DRAWLIST_ARCFAST_SAMPLE_MAX, 0);
|
||||
draw_list->_Path.Size--;
|
||||
}
|
||||
else
|
||||
{
|
||||
num_segments = ImClamp(num_segments, 3, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX);
|
||||
|
||||
const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
|
||||
draw_list->PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1);
|
||||
}
|
||||
|
||||
draw_list->PathStroke(col, ImDrawFlags_Closed, thickness);
|
||||
}
|
||||
|
||||
void c_draw::add_text(ImDrawList* draw_list, const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect)
|
||||
{
|
||||
if ((col & IM_COL32_A_MASK) == 0) return;
|
||||
if (text_begin == text_end || text_begin[0] == 0) return;
|
||||
|
||||
if (text_end == NULL) text_end = text_begin + strlen(text_begin);
|
||||
if (font == NULL) font = draw_list->_Data->Font;
|
||||
if (font_size == 0.0f) font_size = draw_list->_Data->FontSize;
|
||||
|
||||
IM_ASSERT(font->ContainerAtlas->TexID == draw_list->_CmdHeader.TextureId);
|
||||
|
||||
ImVec4 clip_rect = draw_list->_CmdHeader.ClipRect;
|
||||
if (cpu_fine_clip_rect)
|
||||
{
|
||||
clip_rect.x = ImMax(clip_rect.x, cpu_fine_clip_rect->x);
|
||||
clip_rect.y = ImMax(clip_rect.y, cpu_fine_clip_rect->y);
|
||||
clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z);
|
||||
clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w);
|
||||
}
|
||||
font->RenderText(draw_list, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip_rect != NULL);
|
||||
}
|
||||
|
||||
void c_draw::render_text(ImFont* font, ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, ImU32 color, const char* text, const char* text_display_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect)
|
||||
{
|
||||
gui->push_font(font);
|
||||
|
||||
ImVec2 pos = pos_min;
|
||||
const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_display_end, false, 0.0f);
|
||||
|
||||
const ImVec2* clip_min = clip_rect ? &clip_rect->Min : &pos_min;
|
||||
const ImVec2* clip_max = clip_rect ? &clip_rect->Max : &pos_max;
|
||||
bool need_clipping = (pos.x + text_size.x >= clip_max->x) || (pos.y + text_size.y >= clip_max->y);
|
||||
if (clip_rect) need_clipping |= (pos.x < clip_min->x) || (pos.y < clip_min->y);
|
||||
|
||||
if (align.x > 0.0f) pos.x = ImMax(pos.x, pos.x + (pos_max.x - pos.x - text_size.x) * align.x);
|
||||
if (align.y > 0.0f) pos.y = ImMax(pos.y, pos.y + (pos_max.y - pos.y - text_size.y) * align.y);
|
||||
|
||||
if (need_clipping)
|
||||
{
|
||||
ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y);
|
||||
add_text(draw_list, NULL, 0, pos, color, text, text_display_end, 0.0f, &fine_clip_rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
add_text(draw_list, NULL, 0, pos, color, text, text_display_end, 0.0f, NULL);
|
||||
}
|
||||
gui->pop_font();
|
||||
}
|
||||
|
||||
void c_draw::render_text_with_spacing(const char* text, float spacing, ImVec2 position1, ImVec2 position2, ImU32 color, bool centered)
|
||||
{
|
||||
ImVec2 pos = position1;
|
||||
|
||||
float max_width = 0.0f;
|
||||
float total_height = 0.0f;
|
||||
const char* temp = text;
|
||||
while (*temp)
|
||||
{
|
||||
if (*temp != '\n' && *temp != ' ')
|
||||
{
|
||||
float width = ImGui::CalcTextSize(temp, temp + 1).x;
|
||||
if (width > max_width)
|
||||
{
|
||||
max_width = width;
|
||||
}
|
||||
total_height += ImGui::GetTextLineHeight() + spacing;
|
||||
}
|
||||
temp++;
|
||||
}
|
||||
total_height -= spacing;
|
||||
|
||||
if (centered)
|
||||
{
|
||||
float center_x = (position1.x + position2.x) / 2.0f;
|
||||
float center_y = (position1.y + position2.y) / 2.0f;
|
||||
pos.x = center_x - max_width / 2.0f;
|
||||
pos.y = center_y - total_height / 2.0f;
|
||||
}
|
||||
|
||||
while (*text)
|
||||
{
|
||||
if (*text != '\n' && *text != ' ')
|
||||
{
|
||||
ImGui::SetCursorScreenPos(pos);
|
||||
ImGui::TextColored(ImGui::ColorConvertU32ToFloat4(color), "%c", *text);
|
||||
pos.y += ImGui::GetTextLineHeight() + spacing;
|
||||
}
|
||||
text++;
|
||||
}
|
||||
}
|
||||
|
||||
void c_draw::add_image(ImDrawList* draw_list, ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col)
|
||||
{
|
||||
if ((col & IM_COL32_A_MASK) == 0) return;
|
||||
|
||||
const bool push_texture_id = user_texture_id != draw_list->_CmdHeader.TextureId;
|
||||
if (push_texture_id) draw_list->PushTextureID(user_texture_id);
|
||||
|
||||
draw_list->PrimReserve(6, 4);
|
||||
draw_list->PrimRectUV(p_min, p_max, uv_min, uv_max, col);
|
||||
|
||||
if (push_texture_id) draw_list->PopTextureID();
|
||||
}
|
||||
|
||||
void c_draw::add_image_rounded(ImDrawList* draw_list, ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col, float rounding, ImDrawFlags flags)
|
||||
{
|
||||
if ((col & IM_COL32_A_MASK) == 0) return;
|
||||
|
||||
flags = fix_rect_corner_flag(flags);
|
||||
if (rounding < 0.5f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone)
|
||||
{
|
||||
draw->add_image(draw_list, user_texture_id, p_min, p_max, uv_min, uv_max, col);
|
||||
return;
|
||||
}
|
||||
|
||||
const bool push_texture_id = user_texture_id != draw_list->_CmdHeader.TextureId;
|
||||
if (push_texture_id) draw_list->PushTextureID(user_texture_id);
|
||||
|
||||
int vert_start_idx = draw_list->VtxBuffer.Size;
|
||||
draw_list->PathRect(p_min, p_max, rounding, flags);
|
||||
draw_list->PathFillConvex(col);
|
||||
int vert_end_idx = draw_list->VtxBuffer.Size;
|
||||
ImGui::ShadeVertsLinearUV(draw_list, vert_start_idx, vert_end_idx, p_min, p_max, uv_min, uv_max, true);
|
||||
|
||||
if (push_texture_id) draw_list->PopTextureID();
|
||||
}
|
||||
|
||||
void c_draw::add_line(ImDrawList* draw, const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness)
|
||||
{
|
||||
if ((col & IM_COL32_A_MASK) == 0) return;
|
||||
|
||||
draw->PathLineTo(p1 + ImVec2(0.5f, 0.5f));
|
||||
draw->PathLineTo(p2 + ImVec2(0.5f, 0.5f));
|
||||
draw->PathStroke(col, 0, thickness);
|
||||
}
|
||||
|
||||
void c_draw::push_clip_rect(ImDrawList* draw, const ImVec2& cr_min, const ImVec2& cr_max, bool intersect_with_current_clip_rect)
|
||||
{
|
||||
ImVec4 cr(cr_min.x, cr_min.y, cr_max.x, cr_max.y);
|
||||
if (intersect_with_current_clip_rect)
|
||||
{
|
||||
ImVec4 current = draw->_CmdHeader.ClipRect;
|
||||
if (cr.x < current.x) cr.x = current.x;
|
||||
if (cr.y < current.y) cr.y = current.y;
|
||||
if (cr.z > current.z) cr.z = current.z;
|
||||
if (cr.w > current.w) cr.w = current.w;
|
||||
}
|
||||
cr.z = ImMax(cr.x, cr.z);
|
||||
cr.w = ImMax(cr.y, cr.w);
|
||||
|
||||
draw->_ClipRectStack.push_back(cr);
|
||||
draw->_CmdHeader.ClipRect = cr;
|
||||
draw->_OnChangedClipRect();
|
||||
}
|
||||
|
||||
void c_draw::pop_clip_rect(ImDrawList* draw)
|
||||
{
|
||||
draw->_ClipRectStack.pop_back();
|
||||
draw->_CmdHeader.ClipRect = (draw->_ClipRectStack.Size == 0) ? draw->_Data->ClipRectFullscreen : draw->_ClipRectStack.Data[draw->_ClipRectStack.Size - 1];
|
||||
draw->_OnChangedClipRect();
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
#include "../settings/functions.h"
|
||||
|
||||
template<typename TYPE, typename SIGNEDTYPE, typename FLOATTYPE>
|
||||
bool slider_behavior_t(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, TYPE* v, const TYPE v_min, const TYPE v_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
|
||||
const ImGuiAxis axis = (flags & ImGuiSliderFlags_Vertical) ? ImGuiAxis_Y : ImGuiAxis_X;
|
||||
const bool is_logarithmic = (flags & ImGuiSliderFlags_Logarithmic) != 0;
|
||||
const bool is_floating_point = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double);
|
||||
const float v_range_f = (float)(v_min < v_max ? v_max - v_min : v_min - v_max);
|
||||
|
||||
const float grab_padding = 2.0f;
|
||||
const float slider_sz = (bb.Max[axis] - bb.Min[axis]) - grab_padding * 2.0f;
|
||||
float grab_sz = 13.f;
|
||||
const float slider_usable_sz = slider_sz - grab_sz;
|
||||
const float slider_usable_pos_min = bb.Min[axis] + grab_padding + grab_sz * 0.5f;
|
||||
const float slider_usable_pos_max = bb.Max[axis] - grab_padding - grab_sz * 0.5f;
|
||||
|
||||
float logarithmic_zero_epsilon = 0.0f;
|
||||
float zero_deadzone_halfsize = 0.0f;
|
||||
if (is_logarithmic)
|
||||
{
|
||||
const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 1;
|
||||
logarithmic_zero_epsilon = ImPow(0.1f, (float)decimal_precision);
|
||||
zero_deadzone_halfsize = (style.LogSliderDeadzone * 0.5f) / ImMax(slider_usable_sz, 1.0f);
|
||||
}
|
||||
|
||||
bool value_changed = false;
|
||||
if (g.ActiveId == id)
|
||||
{
|
||||
bool set_new_value = false;
|
||||
float clicked_t = 0.0f;
|
||||
if (g.ActiveIdSource == ImGuiInputSource_Mouse)
|
||||
{
|
||||
if (!g.IO.MouseDown[0])
|
||||
{
|
||||
ClearActiveID();
|
||||
}
|
||||
else
|
||||
{
|
||||
const float mouse_abs_pos = g.IO.MousePos[axis];
|
||||
if (g.ActiveIdIsJustActivated)
|
||||
{
|
||||
float grab_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, *v, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
if (axis == ImGuiAxis_Y)
|
||||
grab_t = 1.0f - grab_t;
|
||||
const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t);
|
||||
const bool clicked_around_grab = (mouse_abs_pos >= grab_pos - grab_sz * 0.5f - 1.0f) && (mouse_abs_pos <= grab_pos + grab_sz * 0.5f + 1.0f);
|
||||
g.SliderGrabClickOffset = (clicked_around_grab && is_floating_point) ? mouse_abs_pos - grab_pos : 0.0f;
|
||||
}
|
||||
if (slider_usable_sz > 0.0f)
|
||||
clicked_t = ImSaturate((mouse_abs_pos - g.SliderGrabClickOffset - slider_usable_pos_min) / slider_usable_sz);
|
||||
if (axis == ImGuiAxis_Y)
|
||||
clicked_t = 1.0f - clicked_t;
|
||||
set_new_value = true;
|
||||
}
|
||||
}
|
||||
else if (g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad)
|
||||
{
|
||||
if (g.ActiveIdIsJustActivated)
|
||||
{
|
||||
g.SliderCurrentAccum = 0.0f;
|
||||
g.SliderCurrentAccumDirty = false;
|
||||
}
|
||||
|
||||
float input_delta = (axis == ImGuiAxis_X) ? GetNavTweakPressedAmount(axis) : -GetNavTweakPressedAmount(axis);
|
||||
if (input_delta != 0.0f)
|
||||
{
|
||||
const bool tweak_slow = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakSlow : ImGuiKey_NavKeyboardTweakSlow);
|
||||
const bool tweak_fast = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakFast : ImGuiKey_NavKeyboardTweakFast);
|
||||
const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0;
|
||||
if (decimal_precision > 0)
|
||||
{
|
||||
input_delta /= 100.0f;
|
||||
if (tweak_slow)
|
||||
input_delta /= 10.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((v_range_f >= -100.0f && v_range_f <= 100.0f && v_range_f != 0.0f) || tweak_slow)
|
||||
input_delta = ((input_delta < 0.0f) ? -1.0f : +1.0f) / v_range_f;
|
||||
else
|
||||
input_delta /= 100.0f;
|
||||
}
|
||||
if (tweak_fast)
|
||||
input_delta *= 10.0f;
|
||||
|
||||
g.SliderCurrentAccum += input_delta;
|
||||
g.SliderCurrentAccumDirty = true;
|
||||
}
|
||||
|
||||
float delta = g.SliderCurrentAccum;
|
||||
if (g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated)
|
||||
{
|
||||
ClearActiveID();
|
||||
}
|
||||
else if (g.SliderCurrentAccumDirty)
|
||||
{
|
||||
clicked_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, *v, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
|
||||
if ((clicked_t >= 1.0f && delta > 0.0f) || (clicked_t <= 0.0f && delta < 0.0f))
|
||||
{
|
||||
set_new_value = false;
|
||||
g.SliderCurrentAccum = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_new_value = true;
|
||||
float old_clicked_t = clicked_t;
|
||||
clicked_t = ImSaturate(clicked_t + delta);
|
||||
|
||||
TYPE v_new = ScaleValueFromRatioT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, clicked_t, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
if (is_floating_point && !(flags & ImGuiSliderFlags_NoRoundToFormat))
|
||||
v_new = RoundScalarWithFormatT<TYPE>(format, data_type, v_new);
|
||||
float new_clicked_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_new, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
|
||||
if (delta > 0)
|
||||
g.SliderCurrentAccum -= ImMin(new_clicked_t - old_clicked_t, delta);
|
||||
else
|
||||
g.SliderCurrentAccum -= ImMax(new_clicked_t - old_clicked_t, delta);
|
||||
}
|
||||
|
||||
g.SliderCurrentAccumDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_new_value)
|
||||
if ((g.LastItemData.InFlags & ImGuiItemFlags_ReadOnly) || (flags & ImGuiSliderFlags_ReadOnly))
|
||||
set_new_value = false;
|
||||
|
||||
if (set_new_value)
|
||||
{
|
||||
TYPE v_new = ScaleValueFromRatioT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, clicked_t, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
|
||||
if (is_floating_point && !(flags & ImGuiSliderFlags_NoRoundToFormat)) v_new = RoundScalarWithFormatT<TYPE>(format, data_type, v_new);
|
||||
|
||||
if (*v != v_new)
|
||||
{
|
||||
*v = v_new;
|
||||
value_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (slider_sz < 1.0f)
|
||||
{
|
||||
*out_grab_bb = ImRect(bb.Min, bb.Min);
|
||||
}
|
||||
else
|
||||
{
|
||||
float grab_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, *v, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
if (axis == ImGuiAxis_Y)
|
||||
grab_t = 1.0f - grab_t;
|
||||
const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t);
|
||||
if (axis == ImGuiAxis_X)
|
||||
*out_grab_bb = ImRect(grab_pos - grab_sz * 0.5f, bb.Min.y + grab_padding, grab_pos + grab_sz * 0.5f, bb.Max.y - grab_padding);
|
||||
else
|
||||
*out_grab_bb = ImRect(bb.Min.x + grab_padding, grab_pos - grab_sz * 0.5f, bb.Max.x - grab_padding, grab_pos + grab_sz * 0.5f);
|
||||
}
|
||||
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
bool slider_behavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* p_v, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb)
|
||||
{
|
||||
IM_ASSERT((flags == 1 || (flags & ImGuiSliderFlags_InvalidMask_) == 0) && "Invalid ImGuiSliderFlags flag! Has the 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead.");
|
||||
|
||||
switch (data_type)
|
||||
{
|
||||
case ImGuiDataType_S8: { ImS32 v32 = (ImS32) * (ImS8*)p_v; bool r = slider_behavior_t<ImS32, ImS32, float>(bb, id, ImGuiDataType_S32, &v32, *(const ImS8*)p_min, *(const ImS8*)p_max, format, flags, out_grab_bb); if (r) *(ImS8*)p_v = (ImS8)v32; return r; }
|
||||
case ImGuiDataType_U8: { ImU32 v32 = (ImU32) * (ImU8*)p_v; bool r = slider_behavior_t<ImU32, ImS32, float>(bb, id, ImGuiDataType_U32, &v32, *(const ImU8*)p_min, *(const ImU8*)p_max, format, flags, out_grab_bb); if (r) *(ImU8*)p_v = (ImU8)v32; return r; }
|
||||
case ImGuiDataType_S16: { ImS32 v32 = (ImS32) * (ImS16*)p_v; bool r = slider_behavior_t<ImS32, ImS32, float>(bb, id, ImGuiDataType_S32, &v32, *(const ImS16*)p_min, *(const ImS16*)p_max, format, flags, out_grab_bb); if (r) *(ImS16*)p_v = (ImS16)v32; return r; }
|
||||
case ImGuiDataType_U16: { ImU32 v32 = (ImU32) * (ImU16*)p_v; bool r = slider_behavior_t<ImU32, ImS32, float>(bb, id, ImGuiDataType_U32, &v32, *(const ImU16*)p_min, *(const ImU16*)p_max, format, flags, out_grab_bb); if (r) *(ImU16*)p_v = (ImU16)v32; return r; }
|
||||
case ImGuiDataType_S32:
|
||||
IM_ASSERT(*(const ImS32*)p_min >= INT_MIN / 2 && *(const ImS32*)p_max <= INT_MAX / 2);
|
||||
return slider_behavior_t<ImS32, ImS32, float >(bb, id, data_type, (ImS32*)p_v, *(const ImS32*)p_min, *(const ImS32*)p_max, format, flags, out_grab_bb);
|
||||
case ImGuiDataType_U32:
|
||||
IM_ASSERT(*(const ImU32*)p_max <= UINT_MAX / 2);
|
||||
return slider_behavior_t<ImU32, ImS32, float >(bb, id, data_type, (ImU32*)p_v, *(const ImU32*)p_min, *(const ImU32*)p_max, format, flags, out_grab_bb);
|
||||
case ImGuiDataType_S64:
|
||||
IM_ASSERT(*(const ImS64*)p_min >= LLONG_MIN / 2 && *(const ImS64*)p_max <= LLONG_MAX / 2);
|
||||
return slider_behavior_t<ImS64, ImS64, double>(bb, id, data_type, (ImS64*)p_v, *(const ImS64*)p_min, *(const ImS64*)p_max, format, flags, out_grab_bb);
|
||||
case ImGuiDataType_U64:
|
||||
IM_ASSERT(*(const ImU64*)p_max <= ULLONG_MAX / 2);
|
||||
return slider_behavior_t<ImU64, ImS64, double>(bb, id, data_type, (ImU64*)p_v, *(const ImU64*)p_min, *(const ImU64*)p_max, format, flags, out_grab_bb);
|
||||
case ImGuiDataType_Float:
|
||||
IM_ASSERT(*(const float*)p_min >= -FLT_MAX / 2.0f && *(const float*)p_max <= FLT_MAX / 2.0f);
|
||||
return slider_behavior_t<float, float, float >(bb, id, data_type, (float*)p_v, *(const float*)p_min, *(const float*)p_max, format, flags, out_grab_bb);
|
||||
case ImGuiDataType_Double:
|
||||
IM_ASSERT(*(const double*)p_min >= -DBL_MAX / 2.0f && *(const double*)p_max <= DBL_MAX / 2.0f);
|
||||
return slider_behavior_t<double, double, double>(bb, id, data_type, (double*)p_v, *(const double*)p_min, *(const double*)p_max, format, flags, out_grab_bb);
|
||||
case ImGuiDataType_COUNT: break;
|
||||
}
|
||||
IM_ASSERT(0);
|
||||
return{ false };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct c_slider {
|
||||
ImVec4 text = clr->c_text.text;
|
||||
float grab_slide{ 0.f }, grab_offset{ 0.f }, circle{ 8.f };
|
||||
float alpha{ 0 };
|
||||
bool selected[5];
|
||||
float height[5];
|
||||
float alphab[5];
|
||||
T slow_value{ 0 };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
bool slider_scalar(std::string_view label, ImGuiDataType data_type, T* p_data, const T* p_min, const T* p_max, float power, const char* format)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label.data());
|
||||
|
||||
const float width = GetContentRegionAvail().x;
|
||||
const float height = SCALE(30);
|
||||
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
|
||||
const ImRect rect(pos, pos + ImVec2(width, height));
|
||||
const ImRect slider(pos + ImVec2(width - SCALE(55), 4), pos + ImVec2(width, height - SCALE(4)));
|
||||
|
||||
ItemSize(ImRect(rect.Min, rect.Max));
|
||||
if (!ItemAdd(rect, id)) return false;
|
||||
|
||||
if (!format) format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||
bool hovered = ItemHoverable(slider, id, g.LastItemData.InFlags), held, pressed = ButtonBehavior(ImRect(rect.Min, rect.Max), id, &hovered, &held, NULL);
|
||||
|
||||
ImRect grab_bb;
|
||||
const bool value_changed = slider_behavior(ImRect(slider.Min, slider.Max), id, data_type, p_data, p_min, p_max, format, NULL, &grab_bb);
|
||||
char value_buf[64];
|
||||
|
||||
if (value_changed) MarkItemEdited(id);
|
||||
|
||||
c_slider<T>* state = gui->anim_container(&state, id);
|
||||
|
||||
state->grab_slide = ImLerp(state->grab_slide, grab_bb.Min.x - slider.Min.x, gui->fixed_speed(25.f));
|
||||
state->alpha = ImLerp(state->alpha, hovered ? 1.f : 0.f, gui->fixed_speed(8.f));
|
||||
state->text = ImLerp(state->text, IsItemActive() ? clr->c_text.text_active : hovered ? clr->c_text.text_hov : clr->c_text.text, gui->fixed_speed(8.f));
|
||||
|
||||
draw->add_rect_filled(window->DrawList, slider.Min, slider.Max, gui->get_clr(clr->c_element.layout), set->c_element.rounding);
|
||||
|
||||
if (hovered)
|
||||
set->c_window.slider_id = id;
|
||||
|
||||
if (set->c_window.slider_id == id)
|
||||
set->c_window.slider_hovered = hovered;
|
||||
|
||||
T* f_data = static_cast<T*>(p_data);
|
||||
const T* f_min = static_cast<const T*>(p_min);
|
||||
const T* f_max = static_cast<const T*>(p_max);
|
||||
|
||||
const int num_bars = 5;
|
||||
|
||||
float bar_width = SCALE(3);
|
||||
float bar_spacing = (slider.GetWidth() - num_bars * bar_width) / (num_bars);
|
||||
|
||||
for (int i = 0; i < num_bars; ++i) {
|
||||
float side_padding = SCALE(6.f);
|
||||
float x = slider.Min.x + (slider.GetWidth() - side_padding) / num_bars * i;
|
||||
state->alphab[i] = ImLerp(state->alphab[i], state->selected[i] ? 1.f : 0.1f, gui->fixed_speed(12.f));
|
||||
|
||||
state->height[i] = ImLerp(state->height[i], state->selected[i] ? SCALE(8.f) : SCALE(5.f), gui->fixed_speed(8.f));
|
||||
|
||||
float lower_bound = *f_min + (*f_max - *f_min) * (i * 0.25f);
|
||||
float upper_bound = *f_min + (*f_max - *f_min) * ((i + 1) * 0.25);
|
||||
|
||||
if (*f_data >= lower_bound && *f_data < upper_bound)
|
||||
state->selected[i] = true;
|
||||
else
|
||||
state->selected[i] = false;
|
||||
|
||||
draw->add_rect_filled(window->DrawList, ImVec2(x + side_padding, slider.GetCenter().y - state->height[i]), ImVec2(x + bar_width + side_padding, slider.GetCenter().y + state->height[i]), gui->get_clr(clr->c_other_clr.accent_clr, state->alphab[i]), 30);
|
||||
}
|
||||
|
||||
T* data_ptr = static_cast<T*>(p_data);
|
||||
T target_value = *data_ptr;
|
||||
|
||||
if (hovered)
|
||||
{
|
||||
if (*f_data < *f_max)
|
||||
{
|
||||
if (GetIO().MouseWheel > 0.0f)
|
||||
{
|
||||
*data_ptr += power;
|
||||
}
|
||||
}
|
||||
|
||||
if (*f_data > *f_min)
|
||||
{
|
||||
if (GetIO().MouseWheel < 0.0f)
|
||||
{
|
||||
*data_ptr -= power;
|
||||
}
|
||||
}
|
||||
|
||||
*f_data = ImClamp(*f_data, *f_min, *f_max);
|
||||
}
|
||||
|
||||
if constexpr (std::is_arithmetic_v<T>) {
|
||||
|
||||
T step = (target_value - state->slow_value) * gui->fixed_speed(15.f);
|
||||
if (step == 0 && state->slow_value != target_value) step = (target_value > state->slow_value) ? 1 : -1;
|
||||
state->slow_value += step;
|
||||
}
|
||||
|
||||
snprintf(value_buf, sizeof(value_buf), format, state->slow_value);
|
||||
|
||||
draw->render_text(set->c_font.inter_medium[0], window->DrawList, rect.Min, rect.Max, gui->get_clr(state->text), label.data(), NULL, NULL, { 0.0, 0.5 }, NULL);
|
||||
draw->render_text(set->c_font.inter_medium[0], window->DrawList, rect.Min, rect.Max - SCALE(70, 0), gui->get_clr(state->text), value_buf, NULL, NULL, {1.0, 0.5}, NULL);
|
||||
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
bool c_widget::slider_float(std::string_view label, float* v, float v_min, float v_max, float power, const char* format)
|
||||
{
|
||||
return slider_scalar<float>(label, ImGuiDataType_Float, v, &v_min, &v_max, power, format);
|
||||
}
|
||||
|
||||
bool c_widget::slider_int(std::string_view label, int* v, int v_min, int v_max, int power, const char* format)
|
||||
{
|
||||
return slider_scalar<int>(label, ImGuiDataType_S32, v, &v_min, &v_max, power, format);
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
#include "../settings/functions.h"
|
||||
|
||||
static float calc_combo_size(int items_count, float item_size)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (items_count <= 0) return FLT_MAX;
|
||||
|
||||
return item_size * items_count + g.Style.ItemSpacing.y * (items_count - 1);
|
||||
}
|
||||
|
||||
static const char* items_array_getter(void* data, int idx)
|
||||
{
|
||||
const char* const* items = (const char* const*)data;
|
||||
return items[idx];
|
||||
}
|
||||
|
||||
bool selectable_ex(std::string_view label, bool active, ImDrawFlags rounded_flag)
|
||||
{
|
||||
struct c_selectable
|
||||
{
|
||||
float alpha{ 0.f }, offset{ 0.f };
|
||||
ImVec4 rect{ clr->c_element.layout }, text{ clr->c_text.text };
|
||||
};
|
||||
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems) return false;
|
||||
|
||||
ImGuiContext& g{ *GImGui };
|
||||
const ImGuiStyle& style{ g.Style };
|
||||
const ImGuiID id{ window->GetID(label.data()) };
|
||||
|
||||
const float width{ GetContentRegionAvail().x };
|
||||
float rect_size{ SCALE(30.f) };
|
||||
|
||||
const ImVec2 pos{ window->DC.CursorPos };
|
||||
const ImRect rect(pos, pos + ImVec2(width, rect_size));
|
||||
|
||||
ItemSize(rect, 0);
|
||||
if (!ItemAdd(rect, id)) return false;
|
||||
|
||||
bool hovered{ IsItemHovered() }, pressed{ hovered && g.IO.MouseClicked[0] };
|
||||
if (pressed) MarkItemEdited(id);
|
||||
|
||||
c_selectable* state{ gui->anim_container(&state, id) };
|
||||
|
||||
state->alpha = ImClamp(state->alpha + (gui->fixed_speed(6.f) * (active ? 1.f : -1.f)), 0.f, 1.f);
|
||||
state->text = ImLerp(state->text, active ? clr->c_other_clr.accent_clr : clr->c_text.text_active, gui->fixed_speed(set->c_element.rounding));
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max, gui->get_clr(clr->c_element.dropdown_selection_layout, state->alpha), SCALE(set->c_element.rounding), rounded_flag);
|
||||
draw->render_text(set->c_font.inter_medium[0], window->DrawList, rect.Min + SCALE(7, 0), rect.Max, gui->get_clr(state->text), label.data(), NULL, NULL, { 0.0, 0.5 }, NULL);
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool selectable(const char* label, bool* p_selected, ImDrawFlags rounded_flag)
|
||||
{
|
||||
if (selectable_ex(label, *p_selected, rounded_flag))
|
||||
{
|
||||
*p_selected = !*p_selected;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dropdown_list(std::string_view label, std::string_view preview_value, int val, int max_count, ImGuiComboFlags flags, bool multi)
|
||||
{
|
||||
struct c_combo
|
||||
{
|
||||
ImVec4 text{ clr->c_text.text };
|
||||
bool combo_opened = false, hovered = false;
|
||||
float alpha{ 0.f }, offset{ 0.f };
|
||||
float text_size;
|
||||
};
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
ImGuiNextWindowDataFlags backup_next_window_data_flags = g.NextWindowData.Flags;
|
||||
g.NextWindowData.ClearFlags();
|
||||
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label.data());
|
||||
|
||||
if (val > max_count) val = max_count;
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
|
||||
const float width = GetContentRegionAvail().x;
|
||||
const float rect_size = SCALE(30.f);
|
||||
|
||||
const ImRect rect(pos, pos + ImVec2(width, rect_size));
|
||||
const ImRect combo(pos + ImVec2(0, SCALE(2)), pos + ImVec2(width, rect_size - SCALE(2)));
|
||||
|
||||
ImRect open_combo(pos + ImVec2(width - SCALE(60), SCALE(2)), pos + ImVec2(width, rect_size - SCALE(2)));
|
||||
|
||||
ItemSize(rect, 0.f);
|
||||
if (!ItemAdd(rect, id)) return false;
|
||||
|
||||
bool hovered, held, pressed = ButtonBehavior(rect, id, &hovered, &held);
|
||||
|
||||
c_combo* state = gui->anim_container(&state, id);
|
||||
if (hovered && g.IO.MouseClicked[0] || state->combo_opened && g.IO.MouseClicked[0] && !state->hovered) state->combo_opened = !state->combo_opened;
|
||||
|
||||
state->offset = ImLerp(state->offset, state->combo_opened ? SCALE(5.f) : SCALE(25.f), gui->fixed_speed(12.f) );
|
||||
state->alpha = ImClamp(state->alpha + (gui->fixed_speed(4.f) * (state->combo_opened ? 1.f : -1.f)), 0.f, 1.f);
|
||||
state->text = ImLerp(state->text, state->combo_opened ? clr->c_text.text_active : hovered ? clr->c_text.text_hov : clr->c_text.text, gui->fixed_speed(8.f));
|
||||
|
||||
if (!IsRectVisible(rect.Min, rect.Max + ImVec2(0, 2)))
|
||||
{
|
||||
state->combo_opened = false;
|
||||
state->alpha = 0.f;
|
||||
}
|
||||
|
||||
state->text_size = ImLerp(state->text_size, CalcTextSize(preview_value.data()).x < width - CalcTextSize(label.data()).x - 60 ? CalcTextSize(preview_value.data()).x : width - CalcTextSize(label.data()).x - 60, g.IO.DeltaTime * 8.f);
|
||||
open_combo.Min.x -= state->text_size;
|
||||
|
||||
draw->add_rect_filled(window->DrawList, open_combo.Min, open_combo.Max, gui->get_clr(clr->c_element.layout), SCALE(set->c_element.rounding));
|
||||
draw->render_text(set->c_font.inter_medium[0], window->DrawList, open_combo.Min + SCALE(10, 0), open_combo.Max - ImVec2(rect_size, 0), gui->get_clr(clr->c_text.text_active), preview_value.data(), NULL, NULL, { 0.0, 0.5 }, NULL);
|
||||
|
||||
draw->render_text(set->c_font.icon[0], window->DrawList, open_combo.Max - ImVec2(rect_size, rect_size), open_combo.Max, gui->get_clr(clr->c_text.text), "G", NULL, NULL, { 0.5, 0.60 }, NULL);
|
||||
draw->render_text(set->c_font.inter_medium[0], window->DrawList, rect.Min, rect.Max, gui->get_clr(state->text), label.data(), NULL, NULL, { 0.0, 0.5 }, NULL);
|
||||
|
||||
if (!state->combo_opened && state->alpha < 0.01f) return false;
|
||||
|
||||
gui->push_style_var(ImGuiStyleVar_Alpha, state->alpha);
|
||||
gui->push_style_var(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
gui->push_style_var(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0 ));
|
||||
|
||||
gui->push_style_var(ImGuiStyleVar_WindowRounding, set->c_element.rounding);
|
||||
gui->push_style_var(ImGuiStyleVar_WindowBorderSize, 0.f);
|
||||
|
||||
gui->push_style_color(ImGuiCol_WindowBg, gui->get_clr(clr->c_element.layout));
|
||||
|
||||
gui->set_next_window_pos(open_combo.GetBL() + ImVec2(0, state->offset));
|
||||
gui->set_next_window_size(ImVec2(open_combo.GetWidth(), calc_combo_size(val, rect_size)));
|
||||
|
||||
gui->begin(label, NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoMove);
|
||||
{
|
||||
gui->begin_group();
|
||||
state->hovered = IsWindowHovered();
|
||||
|
||||
if (!multi)
|
||||
if (IsWindowHovered() && g.IO.MouseClicked[0]) state->combo_opened = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void end_combo()
|
||||
{
|
||||
gui->end_group();
|
||||
|
||||
gui->pop_style_color(1);
|
||||
gui->pop_style_var(5);
|
||||
gui->end();
|
||||
}
|
||||
|
||||
bool combo(std::string_view label, int* current_item, std::vector<std::string>& items, int popup_max_height_in_items, int max_count)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
const std::string* preview_value = nullptr;
|
||||
if (*current_item >= 0 && *current_item < static_cast<int>(items.size()))
|
||||
preview_value = &items[*current_item];
|
||||
|
||||
if (popup_max_height_in_items != -1 && !(g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint))
|
||||
SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, calc_combo_size(popup_max_height_in_items, 30)));
|
||||
|
||||
if (!dropdown_list(label.data(), preview_value ? preview_value->c_str() : nullptr, static_cast<int>(items.size()), max_count, ImGuiComboFlags_None, false))
|
||||
return false;
|
||||
|
||||
bool value_changed = false;
|
||||
for (int i = 0; i < static_cast<int>(items.size()); i++)
|
||||
{
|
||||
const std::string& item_text = items[i];
|
||||
PushID(i);
|
||||
const bool item_selected = (i == *current_item);
|
||||
if (selectable_ex(item_text.c_str(), item_selected, i == 0 ? ImDrawFlags_RoundCornersTop : i == items.size() - 1 ? ImDrawFlags_RoundCornersBottom : ImDrawFlags_RoundCornersNone) && *current_item != i)
|
||||
{
|
||||
value_changed = true;
|
||||
*current_item = i;
|
||||
}
|
||||
|
||||
if (g.IO.MouseClicked[1])
|
||||
|
||||
if (item_selected) SetItemDefaultFocus();
|
||||
PopID();
|
||||
}
|
||||
|
||||
end_combo();
|
||||
|
||||
if (value_changed) MarkItemEdited(g.LastItemData.ID);
|
||||
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
bool c_widget::dropdown(std::string_view label, int* current_item, std::vector<std::string>& items, int max_count)
|
||||
{
|
||||
const bool value_changed{ combo(label, current_item, items, -1, max_count) };
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
void c_widget::multi_dropdown(std::string_view label, bool variable[], std::vector<std::string>& labels, int max_count)
|
||||
{
|
||||
ImGuiContext& g{ *GImGui };
|
||||
|
||||
std::string preview{ "Select" };
|
||||
|
||||
for (auto i = 0, j = 0; i < labels.size(); i++)
|
||||
{
|
||||
if (variable[i])
|
||||
{
|
||||
if (j)
|
||||
preview += (", ") + (std::string)labels[i];
|
||||
else
|
||||
preview = labels[i];
|
||||
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if (dropdown_list(label.data(), preview.c_str(), labels.size(), max_count, 0, true))
|
||||
{
|
||||
for (auto i = 0; i < labels.size(); i++) selectable(labels[i].data(), &variable[i], i == 0 ? ImDrawFlags_RoundCornersTop : i == labels.size() - 1 ? ImDrawFlags_RoundCornersBottom : ImDrawFlags_RoundCornersNone);
|
||||
|
||||
end_combo();
|
||||
}
|
||||
|
||||
preview = ("Select");
|
||||
}
|
||||
|
||||
bool tool_dropdown_list(std::string_view label, std::string_view preview_value, int val, int max_count, ImGuiComboFlags flags, bool multi)
|
||||
{
|
||||
struct c_combo
|
||||
{
|
||||
ImVec4 text{ clr->c_text.text };
|
||||
bool combo_opened = false, hovered = false;
|
||||
float alpha{ 0.f }, offset{ 0.f };
|
||||
};
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
ImGuiNextWindowDataFlags backup_next_window_data_flags = g.NextWindowData.Flags;
|
||||
g.NextWindowData.ClearFlags();
|
||||
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label.data());
|
||||
|
||||
if (val > max_count) val = max_count;
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
|
||||
const ImRect rect(pos, pos + SCALE(130, 36));
|
||||
|
||||
ItemSize(rect, 0.f);
|
||||
if (!ItemAdd(rect, id)) return false;
|
||||
|
||||
bool hovered, held, pressed = ButtonBehavior(rect, id, &hovered, &held);
|
||||
|
||||
c_combo* state = gui->anim_container(&state, id);
|
||||
if (hovered && g.IO.MouseClicked[0] || state->combo_opened && g.IO.MouseClicked[0] && !state->hovered) state->combo_opened = !state->combo_opened;
|
||||
|
||||
state->offset = ImLerp(state->offset, state->combo_opened ? SCALE(5.f) : SCALE(25.f), gui->fixed_speed(12.f) );
|
||||
state->alpha = ImClamp(state->alpha + (gui->fixed_speed(4.f) * (state->combo_opened ? 1.f : -1.f)), 0.f, 1.f);
|
||||
state->text = ImLerp(state->text, state->combo_opened ? clr->c_text.text_active : hovered ? clr->c_text.text_hov : clr->c_text.text, gui->fixed_speed(8.f));
|
||||
|
||||
if (!IsRectVisible(rect.Min, rect.Max + ImVec2(0, 2)))
|
||||
{
|
||||
state->combo_opened = false;
|
||||
state->alpha = 0.f;
|
||||
}
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max, gui->get_clr(clr->c_element.layout), SCALE(set->c_element.rounding));
|
||||
draw->render_text(set->c_font.inter_medium[0], window->DrawList, rect.Min + SCALE(10, 0), rect.Max - ImVec2(SCALE(36.f), 0), gui->get_clr(clr->c_text.text_active), preview_value.data(), NULL, NULL, { 0.0, 0.5 }, NULL);
|
||||
|
||||
draw->render_text(set->c_font.icon[0], window->DrawList, rect.Max - ImVec2(SCALE(36.f), SCALE(36.f)), rect.Max, gui->get_clr(clr->c_text.text), "G", NULL, NULL, { 0.5, 0.50 }, NULL);
|
||||
|
||||
if (!state->combo_opened && state->alpha < 0.01f) return false;
|
||||
|
||||
gui->push_style_var(ImGuiStyleVar_Alpha, state->alpha);
|
||||
gui->push_style_var(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
gui->push_style_var(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0 ));
|
||||
|
||||
gui->push_style_var(ImGuiStyleVar_WindowRounding, set->c_element.rounding);
|
||||
gui->push_style_var(ImGuiStyleVar_WindowBorderSize, 0.f);
|
||||
|
||||
gui->push_style_color(ImGuiCol_WindowBg, gui->get_clr(clr->c_element.layout));
|
||||
|
||||
gui->set_next_window_pos(rect.GetBL() + ImVec2(0, state->offset));
|
||||
gui->set_next_window_size(ImVec2(rect.GetWidth(), calc_combo_size(val, SCALE(30.f))));
|
||||
|
||||
gui->begin(label, NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoMove);
|
||||
{
|
||||
gui->begin_group();
|
||||
state->hovered = IsWindowHovered();
|
||||
|
||||
if (!multi)
|
||||
if (IsWindowHovered() && g.IO.MouseClicked[0]) state->combo_opened = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tool_combo(std::string_view label, int* current_item, std::vector<std::string>& items, int popup_max_height_in_items, int max_count)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
const std::string* preview_value = nullptr;
|
||||
if (*current_item >= 0 && *current_item < static_cast<int>(items.size()))
|
||||
preview_value = &items[*current_item];
|
||||
|
||||
if (popup_max_height_in_items != -1 && !(g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint))
|
||||
SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, calc_combo_size(popup_max_height_in_items, 30)));
|
||||
|
||||
if (!tool_dropdown_list(label.data(), preview_value ? preview_value->c_str() : nullptr, static_cast<int>(items.size()), max_count, ImGuiComboFlags_None, false))
|
||||
return false;
|
||||
|
||||
bool value_changed = false;
|
||||
for (int i = 0; i < static_cast<int>(items.size()); i++)
|
||||
{
|
||||
const std::string& item_text = items[i];
|
||||
PushID(i);
|
||||
const bool item_selected = (i == *current_item);
|
||||
if (selectable_ex(item_text.c_str(), item_selected, i == 0 ? ImDrawFlags_RoundCornersTop : i == items.size() - 1 ? ImDrawFlags_RoundCornersBottom : ImDrawFlags_RoundCornersNone) && *current_item != i)
|
||||
{
|
||||
value_changed = true;
|
||||
*current_item = i;
|
||||
}
|
||||
|
||||
if (g.IO.MouseClicked[1])
|
||||
|
||||
if (item_selected) SetItemDefaultFocus();
|
||||
PopID();
|
||||
}
|
||||
|
||||
end_combo();
|
||||
|
||||
if (value_changed) MarkItemEdited(g.LastItemData.ID);
|
||||
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
bool c_widget::tool_dropdown(std::string_view label, int* current_item, std::vector<std::string>& items, int max_count)
|
||||
{
|
||||
const bool value_changed{ tool_combo(label, current_item, items, -1, max_count) };
|
||||
return value_changed;
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
#include "../settings/functions.h"
|
||||
|
||||
void esp_preview::fill_box(const ImVec2& pos, const ImVec2& size)
|
||||
{
|
||||
box.position = pos;
|
||||
box.size = size;
|
||||
}
|
||||
|
||||
void esp_preview::fill_areas()
|
||||
{
|
||||
area_rect[area_top] = ImRect(box.position - ImVec2(0, area_size), box.position + ImVec2(box.size.x, 0));
|
||||
area_rect[area_bottom] = ImRect(box.position + ImVec2(0, box.size.y), box.position + box.size + ImVec2(0, area_size));
|
||||
area_rect[area_left] = ImRect(box.position - ImVec2(area_size, 0), box.position + ImVec2(0, box.size.y));
|
||||
area_rect[area_right] = ImRect(box.position + ImVec2(box.size.x, 0), box.position + box.size + ImVec2(area_size, 0));
|
||||
|
||||
hovered_area = area_none;
|
||||
|
||||
for (int i = 0; i < IM_ARRAYSIZE(area_rect); i++)
|
||||
{
|
||||
if (ImGui::IsMouseHoveringRect(area_rect[i].Min, area_rect[i].Max)) hovered_area = i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void esp_preview::fill_buffers()
|
||||
{
|
||||
std::fill(std::begin(bars_buffer), std::end(bars_buffer), 0);
|
||||
std::fill(std::begin(texts_buffer), std::end(texts_buffer), 0);
|
||||
|
||||
}
|
||||
|
||||
void esp_preview::initialize_preview(const ImVec2& pos, const ImVec2& size, bool render_text, bool render_bar)
|
||||
{
|
||||
fill_box(pos, size);
|
||||
fill_areas();
|
||||
fill_buffers();
|
||||
|
||||
esp->render_box(0);
|
||||
|
||||
if (render_bar)
|
||||
for (int i = 0; i < esp->bar.size(); i++) esp->render_bar(esp->bar.at(i));
|
||||
|
||||
if (render_text)
|
||||
for (int i = 0; i < esp->text.size(); i++) esp->render_text(esp->text.at(i));
|
||||
|
||||
}
|
||||
|
||||
void esp_preview::render_box(int type)
|
||||
{
|
||||
const ImVec2 box_pos = box.position;
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
|
||||
draw->add_line(GetWindowDrawList(), box.position, box.position + ImVec2(0, box.size.y / 3), gui->get_clr(clr->c_other_clr.white_clr));
|
||||
draw->add_line(GetWindowDrawList(), box.position, box.position + ImVec2(box.size.x / 3, 0), gui->get_clr(clr->c_other_clr.white_clr));
|
||||
|
||||
draw->add_line(GetWindowDrawList(), box.position + ImVec2(box.size.x * 2 / 3, 0), box.position + ImVec2(box.size.x, 0), gui->get_clr(clr->c_other_clr.white_clr));
|
||||
draw->add_line(GetWindowDrawList(), box.position + ImVec2(box.size.x, 0), box.position + ImVec2(box.size.x, box.size.y / 3), gui->get_clr(clr->c_other_clr.white_clr));
|
||||
|
||||
draw->add_line(GetWindowDrawList(), box.position + ImVec2(box.size.x, box.size.y * 2 / 3), box.position + box.size, gui->get_clr(clr->c_other_clr.white_clr));
|
||||
draw->add_line(GetWindowDrawList(), box.position + box.size, box.position + box.size - ImVec2(box.size.x / 3, 0), gui->get_clr(clr->c_other_clr.white_clr));
|
||||
|
||||
draw->add_line(GetWindowDrawList(), box.position + ImVec2(box.size.x / 3, box.size.y), ImVec2(box.position.x, box.position.y + box.size.y), gui->get_clr(clr->c_other_clr.white_clr));
|
||||
draw->add_line(GetWindowDrawList(), ImVec2(box.position.x, box.position.y + box.size.y), box.position + ImVec2(0, box.size.y * 2 / 3), gui->get_clr(clr->c_other_clr.white_clr));
|
||||
}
|
||||
|
||||
void esp_preview::render_text(item_state& state)
|
||||
{
|
||||
const ImVec2 text_size = ImGui::CalcTextSize(state.name.c_str());
|
||||
const ImVec2 box_pos = box.position - ImGui::GetWindowPos();
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
|
||||
ImVec2 pos_offset[]
|
||||
{
|
||||
ImVec2(0.f, texts_buffer[state.position] * -var->c_preview.texts_spacing - bars_buffer[state.position] * var->c_preview.bars_spacing),
|
||||
ImVec2(0.f, texts_buffer[state.position] * var->c_preview.texts_spacing + bars_buffer[state.position] * var->c_preview.bars_spacing),
|
||||
ImVec2(bars_buffer[state.position] * -var->c_preview.bars_spacing, texts_buffer[state.position] * var->c_preview.texts_spacing),
|
||||
ImVec2(bars_buffer[state.position] * var->c_preview.bars_spacing, texts_buffer[state.position] * var->c_preview.texts_spacing),
|
||||
};
|
||||
|
||||
texts_buffer[state.position]++;
|
||||
|
||||
ImVec2 positions[]
|
||||
{
|
||||
ImVec2(box_pos.x + (box.size.x / 2) - text_size.x / 2, box_pos.y - text_size.y - var->c_preview.box_padding) + pos_offset[position_top],
|
||||
ImVec2(box_pos.x + (box.size.x / 2) - text_size.x / 2, box_pos.y + box.size.y + var->c_preview.box_padding) + pos_offset[position_bottom],
|
||||
ImVec2(box_pos.x - text_size.x - var->c_preview.box_padding, box_pos.y) + pos_offset[position_left],
|
||||
ImVec2(box_pos.x + box.size.x + var->c_preview.box_padding, box_pos.y) + pos_offset[position_right],
|
||||
};
|
||||
|
||||
state.location.x = ImLerp(state.location.x, positions[state.position].x, ImGui::GetIO().DeltaTime * var->c_preview.anim_speed);
|
||||
state.location.y = ImLerp(state.location.y, positions[state.position].y, ImGui::GetIO().DeltaTime * var->c_preview.anim_speed);
|
||||
|
||||
if (state.swapped) {
|
||||
if (abs(state.location.x - positions[state.position].x) < 1.f && abs(state.location.y - positions[state.position].y) < 1.f) {
|
||||
state.swapped = false;
|
||||
}
|
||||
}
|
||||
|
||||
ImRect rect = ImRect(ImGui::GetWindowPos() + state.location, ImGui::GetWindowPos() + state.location + ImGui::CalcTextSize(state.name.c_str()));
|
||||
state.rect = rect;
|
||||
|
||||
if (ImGui::IsMouseHoveringRect(rect.Min, rect.Max) && ImGui::IsMouseClicked(0) && ImGui::IsWindowHovered())
|
||||
state.active = true;
|
||||
|
||||
if (state.active)
|
||||
{
|
||||
draw->add_text(window->DrawList, 0, 0, ImGui::GetMousePos() - ImVec2(text_size.x / 2, text_size.y / 2), ImGui::GetColorU32(state.color), state.name.c_str());
|
||||
|
||||
for (auto& stored : text) {
|
||||
if (stored.name == state.name || stored.position != state.position || stored.swapped)
|
||||
continue;
|
||||
|
||||
if (ImGui::IsMouseHoveringRect(stored.rect.Min, stored.rect.Max))
|
||||
{
|
||||
std::swap(state, stored);
|
||||
|
||||
state.active = false;
|
||||
state.swapped = true;
|
||||
|
||||
stored.active = true;
|
||||
stored.swapped = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hovered_area != area_none)
|
||||
{
|
||||
state.position = hovered_area;
|
||||
}
|
||||
|
||||
if (ImGui::IsMouseReleased(0))
|
||||
{
|
||||
state.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
draw->add_text(window->DrawList, 0, 0, rect.Min, ImGui::GetColorU32(state.color), state.name.c_str());
|
||||
|
||||
}
|
||||
|
||||
void esp_preview::render_bar(item_state& state)
|
||||
{
|
||||
const float bar_size = 3.f;
|
||||
const ImVec2 box_pos = box.position - ImGui::GetWindowPos();
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
|
||||
ImVec2 pos_offset[]
|
||||
{
|
||||
ImVec2(0.f, bars_buffer[state.position] * -var->c_preview.bars_spacing),
|
||||
ImVec2(0.f, bars_buffer[state.position] * var->c_preview.bars_spacing),
|
||||
ImVec2(bars_buffer[state.position] * -var->c_preview.bars_spacing, 0.f),
|
||||
ImVec2(bars_buffer[state.position] * var->c_preview.bars_spacing, 0.f),
|
||||
};
|
||||
|
||||
bars_buffer[state.position]++;
|
||||
|
||||
ImVec2 positions[]
|
||||
{
|
||||
ImVec2(box_pos.x, box_pos.y - var->c_preview.box_padding - bar_size) + pos_offset[position_top],
|
||||
ImVec2(box_pos.x, box_pos.y + box.size.y + var->c_preview.box_padding) + pos_offset[position_bottom],
|
||||
ImVec2(box_pos.x - var->c_preview.box_padding - bar_size, box_pos.y) + pos_offset[position_left],
|
||||
ImVec2(box_pos.x + box.size.x + var->c_preview.box_padding, box_pos.y) + pos_offset[position_right],
|
||||
};
|
||||
|
||||
ImVec2 bar_sizes[]
|
||||
{
|
||||
ImVec2(box.size.x, bar_size),
|
||||
ImVec2(box.size.x, bar_size),
|
||||
ImVec2(bar_size, box.size.y),
|
||||
ImVec2(bar_size, box.size.y),
|
||||
};
|
||||
|
||||
state.location.x = ImLerp(state.location.x, positions[state.position].x, ImGui::GetIO().DeltaTime * var->c_preview.anim_speed);
|
||||
state.location.y = ImLerp(state.location.y, positions[state.position].y, ImGui::GetIO().DeltaTime * var->c_preview.anim_speed);
|
||||
|
||||
if (state.swapped) {
|
||||
if (abs(state.location.x - positions[state.position].x) < 1.f && abs(state.location.y - positions[state.position].y) < 1.f) {
|
||||
state.swapped = false;
|
||||
}
|
||||
}
|
||||
|
||||
ImRect rect = ImRect(ImGui::GetWindowPos() + state.location, ImGui::GetWindowPos() + state.location + bar_sizes[state.position]);
|
||||
state.rect = rect;
|
||||
|
||||
if (ImGui::IsMouseHoveringRect(rect.Min, rect.Max) && ImGui::IsMouseClicked(0) && ImGui::IsWindowHovered())
|
||||
state.active = true;
|
||||
|
||||
if (state.active)
|
||||
{
|
||||
draw->add_rect_filled(window->DrawList, ImGui::GetMousePos() - ImVec2(rect.GetWidth() / 2, rect.GetHeight() / 2), ImGui::GetMousePos() + ImVec2(rect.GetWidth() / 2, rect.GetHeight() / 2), ImGui::GetColorU32(state.color));
|
||||
|
||||
for (auto& stored : bar) {
|
||||
if (stored.name == state.name || stored.position != state.position || stored.swapped) continue;
|
||||
|
||||
if (ImGui::IsMouseHoveringRect(stored.rect.Min, stored.rect.Max))
|
||||
{
|
||||
std::swap(state, stored);
|
||||
|
||||
state.active = false;
|
||||
state.swapped = true;
|
||||
|
||||
stored.active = true;
|
||||
stored.swapped = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hovered_area != area_none)
|
||||
{
|
||||
state.position = hovered_area;
|
||||
}
|
||||
|
||||
if (ImGui::IsMouseReleased(0))
|
||||
{
|
||||
state.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max, ImGui::GetColorU32(state.color));
|
||||
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
#include "../settings/functions.h"
|
||||
|
||||
const char* keys[] =
|
||||
{
|
||||
"None",
|
||||
"Mouse 1",
|
||||
"Mouse 2",
|
||||
"CN",
|
||||
"Mouse 3",
|
||||
"Mouse 4",
|
||||
"Mouse 5",
|
||||
"-",
|
||||
"Back",
|
||||
"Tab",
|
||||
"-",
|
||||
"-",
|
||||
"CLR",
|
||||
"Enter",
|
||||
"-",
|
||||
"-",
|
||||
"Shift",
|
||||
"CTL",
|
||||
"Menu",
|
||||
"Pause",
|
||||
"Caps",
|
||||
"KAN",
|
||||
"-",
|
||||
"JUN",
|
||||
"FIN",
|
||||
"KAN",
|
||||
"-",
|
||||
"Escape",
|
||||
"CON",
|
||||
"NCO",
|
||||
"ACC",
|
||||
"MAD",
|
||||
"Space",
|
||||
"PGU",
|
||||
"PGD",
|
||||
"End",
|
||||
"Home",
|
||||
"Left",
|
||||
"Up",
|
||||
"Right",
|
||||
"Down",
|
||||
"SEL",
|
||||
"PRI",
|
||||
"EXE",
|
||||
"PRI",
|
||||
"INS",
|
||||
"Delete",
|
||||
"HEL",
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"A",
|
||||
"B",
|
||||
"C",
|
||||
"D",
|
||||
"E",
|
||||
"F",
|
||||
"G",
|
||||
"H",
|
||||
"I",
|
||||
"J",
|
||||
"K",
|
||||
"L",
|
||||
"M",
|
||||
"N",
|
||||
"O",
|
||||
"P",
|
||||
"Q",
|
||||
"R",
|
||||
"S",
|
||||
"T",
|
||||
"U",
|
||||
"V",
|
||||
"W",
|
||||
"X",
|
||||
"Y",
|
||||
"Z",
|
||||
"WIN",
|
||||
"WIN",
|
||||
"APP",
|
||||
"-",
|
||||
"SLE",
|
||||
"Num 0",
|
||||
"Num 1",
|
||||
"Num 2",
|
||||
"Num 3",
|
||||
"Num 4",
|
||||
"Num 5",
|
||||
"Num 6",
|
||||
"Num 7",
|
||||
"Num 8",
|
||||
"Num 9",
|
||||
"MUL",
|
||||
"ADD",
|
||||
"SEP",
|
||||
"MIN",
|
||||
"Delete",
|
||||
"DIV",
|
||||
"F1",
|
||||
"F2",
|
||||
"F3",
|
||||
"F4",
|
||||
"F5",
|
||||
"F6",
|
||||
"F7",
|
||||
"F8",
|
||||
"F9",
|
||||
"F10",
|
||||
"F11",
|
||||
"F12",
|
||||
"F13",
|
||||
"F14",
|
||||
"F15",
|
||||
"F16",
|
||||
"F17",
|
||||
"F18",
|
||||
"F19",
|
||||
"F20",
|
||||
"F21",
|
||||
"F22",
|
||||
"F23",
|
||||
"F24",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"NUM",
|
||||
"SCR",
|
||||
"EQU",
|
||||
"MAS",
|
||||
"TOY",
|
||||
"OYA",
|
||||
"OYA",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"Shift",
|
||||
"Shift",
|
||||
"Ctrl",
|
||||
"Ctrl",
|
||||
"Alt",
|
||||
"Alt"
|
||||
};
|
||||
|
||||
bool c_widget::keybind(std::string_view label, int* key)
|
||||
{
|
||||
|
||||
struct c_keybind
|
||||
{
|
||||
ImVec4 text{ clr->c_text.text };
|
||||
float slow{ 0 };
|
||||
};
|
||||
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
if (window->SkipItems) return false;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiIO& io = g.IO;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
|
||||
const ImGuiID id = window->GetID(label.data());
|
||||
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
const float width = GetContentRegionAvail().x;
|
||||
const float rect_size{ SCALE(30.f) };
|
||||
|
||||
const ImRect decorate_bb(pos, pos + ImVec2(SCALE(30), rect_size));
|
||||
const ImRect total_bb(pos + SCALE(40, 0), pos + ImVec2(width, rect_size));
|
||||
|
||||
ItemSize(total_bb, 0.f);
|
||||
if (!ItemAdd(total_bb, id, &total_bb)) return false;
|
||||
|
||||
char buf_display[64] = "None";
|
||||
|
||||
bool value_changed = false;
|
||||
int k = *key;
|
||||
|
||||
std::string active_key = "";
|
||||
active_key += keys[*key];
|
||||
|
||||
if (*key != 0 && g.ActiveId != id) {
|
||||
strcpy_s(buf_display, active_key.c_str());
|
||||
}
|
||||
else if (g.ActiveId == id) {
|
||||
strcpy_s(buf_display, "...");
|
||||
}
|
||||
|
||||
bool hovered = ItemHoverable(total_bb, id, 0);
|
||||
|
||||
if (hovered && io.MouseClicked[0])
|
||||
{
|
||||
if (g.ActiveId != id) {
|
||||
memset(io.MouseDown, 0, sizeof(io.MouseDown));
|
||||
memset(io.KeysDown, 0, sizeof(io.KeysDown));
|
||||
*key = 0;
|
||||
}
|
||||
ImGui::SetActiveID(id, window);
|
||||
ImGui::FocusWindow(window);
|
||||
}
|
||||
else if (io.MouseClicked[0]) {
|
||||
|
||||
if (g.ActiveId == id) ImGui::ClearActiveID();
|
||||
}
|
||||
|
||||
if (g.ActiveId == id) {
|
||||
for (auto i = 0; i < 5; i++) {
|
||||
if (io.MouseDown[i]) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
k = 0x01;
|
||||
break;
|
||||
case 1:
|
||||
k = 0x02;
|
||||
break;
|
||||
case 2:
|
||||
k = 0x04;
|
||||
break;
|
||||
case 3:
|
||||
k = 0x05;
|
||||
break;
|
||||
case 4:
|
||||
k = 0x06;
|
||||
break;
|
||||
}
|
||||
value_changed = true;
|
||||
ImGui::ClearActiveID();
|
||||
}
|
||||
}
|
||||
if (!value_changed) {
|
||||
for (auto i = 0x08; i <= 0xA5; i++) {
|
||||
if (io.KeysDown[i]) {
|
||||
k = i;
|
||||
value_changed = true;
|
||||
ImGui::ClearActiveID();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyPressedMap(ImGuiKey_Escape)) {
|
||||
*key = 0;
|
||||
ImGui::ClearActiveID();
|
||||
}
|
||||
else {
|
||||
*key = k;
|
||||
}
|
||||
}
|
||||
|
||||
c_keybind* state = gui->anim_container(&state, id);
|
||||
state->text = ImLerp(state->text, g.ActiveId == id ? clr->c_text.text_active : clr->c_text.text, g.IO.DeltaTime * gui->fixed_speed(8.f));
|
||||
|
||||
draw->add_rect_filled(window->DrawList, decorate_bb.Min, decorate_bb.Max, gui->get_clr(clr->c_element.layout), SCALE(set->c_element.rounding));
|
||||
draw->add_rect_filled(window->DrawList, total_bb.Min, total_bb.Max, gui->get_clr(clr->c_element.layout), SCALE(set->c_element.rounding));
|
||||
|
||||
draw->render_text(set->c_font.icon[1], window->DrawList, decorate_bb.Min, decorate_bb.Max, gui->get_clr(clr->c_other_clr.accent_clr), "E", NULL, NULL, { 0.5, 0.5 }, NULL);
|
||||
draw->render_text(set->c_font.inter_medium[0], window->DrawList, total_bb.Min, total_bb.Max, gui->get_clr(clr->c_text.text_active), buf_display, NULL, NULL, { 0.5, 0.5 }, NULL);
|
||||
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
bool c_widget::keybind_button(std::string_view name_id, bool* pressing)
|
||||
{
|
||||
struct button_state
|
||||
{
|
||||
ImVec4 background_toggle;
|
||||
ImVec4 background_hold;
|
||||
};
|
||||
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(name_id.data());
|
||||
|
||||
const float label_size = CalcTextSize(name_id.data(), NULL, true).x;
|
||||
const float width = GetContentRegionAvail().x;
|
||||
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
ImRect rect(pos, pos + ImVec2(width, SCALE(30)));
|
||||
|
||||
ItemSize(rect, 0);
|
||||
if (!ItemAdd(rect, id)) return false;
|
||||
|
||||
bool hovered, held, pressed = ButtonBehavior(rect, id, &hovered, &held);
|
||||
|
||||
if (pressed)
|
||||
MarkItemEdited(id);
|
||||
|
||||
|
||||
if (IsMouseHoveringRect(rect.Min, rect.Max - ImVec2((width / 2) + SCALE(5), 0), true) && pressed) *pressing = false;
|
||||
if (IsMouseHoveringRect(rect.Min + ImVec2((width / 2) + SCALE(5), 0), rect.Max, true) && pressed) *pressing = true;
|
||||
|
||||
button_state* state = gui->anim_container(&state, id);
|
||||
|
||||
state->background_toggle = ImLerp(state->background_toggle, !*pressing ? clr->c_other_clr.accent_clr : clr->c_element.layout, gui->fixed_speed(8.f));
|
||||
state->background_hold = ImLerp(state->background_hold, *pressing ? clr->c_other_clr.accent_clr : clr->c_element.layout, gui->fixed_speed(8.f));
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max - ImVec2((width / 2) + SCALE(5), 0), gui->get_clr(state->background_toggle), SCALE(set->c_element.rounding));
|
||||
draw->add_rect_filled(window->DrawList, rect.Min + ImVec2((width / 2) + SCALE(5), 0), rect.Max, gui->get_clr(state->background_hold), SCALE(set->c_element.rounding));
|
||||
|
||||
draw->render_text(set->c_font.inter_medium[0], window->DrawList, rect.Min, rect.Max - ImVec2((width / 2) + SCALE(5), 0), gui->get_clr(clr->c_text.text_active), "Toggle", NULL, NULL, { 0.5, 0.5 }, NULL);
|
||||
draw->render_text(set->c_font.inter_medium[0], window->DrawList, rect.Min + ImVec2((width / 2) + SCALE(5), 0), rect.Max, gui->get_clr(clr->c_text.text_active), "Hold", NULL, NULL, { 0.5, 0.5 }, NULL);
|
||||
|
||||
return pressed;
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
#include "../settings/functions.h"
|
||||
|
||||
bool load_button(std::string_view label, bool* callback) {
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label.data());
|
||||
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
ImRect rect(pos, pos + SCALE(100, 40));
|
||||
|
||||
ItemSize(rect, 0);
|
||||
if (!ItemAdd(rect, id)) return false;
|
||||
|
||||
bool hovered = IsItemHovered();
|
||||
bool clicked = hovered && g.IO.MouseClicked[0];
|
||||
|
||||
if (clicked)
|
||||
*callback = !*callback;
|
||||
|
||||
float* state = gui->anim_container(&state, id);
|
||||
*state = ImClamp(*state + (gui->fixed_speed(8.f) * (!*callback ? 1.f : -1.f)), 0.f, 1.f);
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max, gui->get_clr(clr->c_lua.stroke), SCALE(2.f));
|
||||
draw->render_text(window->DrawList, set->c_font.inter_medium[1], rect.Min, rect.Max, gui->get_clr(clr->c_text.text), "UNLOAD", NULL, NULL, ImVec2(0.5f, 0.5f));
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max, gui->get_clr(clr->c_other_clr.accent_clr, *state), SCALE(2.f));
|
||||
draw->render_text(window->DrawList, set->c_font.inter_medium[1], rect.Min, rect.Max, gui->get_clr(clr->c_text.text_active, *state), "LOAD", NULL, NULL, ImVec2(0.5f, 0.5f));
|
||||
|
||||
return clicked;
|
||||
}
|
||||
|
||||
bool c_widget::lua_tool_button(std::string_view icon, std::string_view aid)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID((std::stringstream{} << icon << aid).str().c_str());
|
||||
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
ImRect rect(pos, pos + SCALE(15, 15));
|
||||
|
||||
ItemSize(rect, 0);
|
||||
if (!ItemAdd(rect, id)) return false;
|
||||
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(rect, id, &hovered, &held);
|
||||
|
||||
ImVec4* state = gui->anim_container(&state, id);
|
||||
*state = ImLerp(*state, hovered ? clr->c_text.text_active : clr->c_text.text_hov, gui->fixed_speed(12.f));
|
||||
|
||||
draw->render_text(window->DrawList, set->c_font.icon[3], rect.Min, rect.Max, gui->get_clr(*state), icon.data(), NULL, NULL, ImVec2(0.5f, 0.5f));
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool c_widget::lua_selectable(lua_data* data, int lua_id)
|
||||
{
|
||||
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems) return false;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID((std::stringstream{} << data->name.data() << lua_id).str().c_str());
|
||||
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
const float width = GetContentRegionAvail().x;
|
||||
ImRect rect(pos, pos + ImVec2(width, SCALE(60)));
|
||||
|
||||
ItemSize(rect, 0);
|
||||
if (!ItemAdd(rect, id)) return false;
|
||||
|
||||
draw->add_rect_filled(window->DrawList, rect.Min, rect.Max, gui->get_clr(clr->c_lua.background), SCALE(set->c_child.rounding));
|
||||
draw->add_rect(window->DrawList, rect.Min, rect.Max, gui->get_clr(clr->c_lua.stroke), SCALE(set->c_child.rounding), 0, SCALE(1.f));
|
||||
draw->render_text(window->DrawList, set->c_font.inter_medium[1], rect.Min + SCALE(10, 11), rect.Max, gui->get_clr(clr->c_text.text_active), data->name.data());
|
||||
draw->render_text(window->DrawList, set->c_font.inter_medium[0], rect.Min + SCALE(10, 33), rect.Max, gui->get_clr(clr->c_text.text_active), "Modified:");
|
||||
draw->render_text(window->DrawList, set->c_font.inter_medium[0], rect.Min + SCALE(69, 33), rect.Max, gui->get_clr(clr->c_other_clr.accent_clr), data->date.data());
|
||||
|
||||
const ImVec2 stored_cursor_pos = GetCursorScreenPos();
|
||||
|
||||
SetCursorScreenPos(ImVec2(rect.Max.x - SCALE(110), rect.Min.y + SCALE(10)));
|
||||
load_button((std::stringstream{} << data->name << id).str(), &data->loaded);
|
||||
|
||||
SetCursorScreenPos(ImVec2(rect.Max.x - SCALE(146), rect.Min.y + SCALE(23)));
|
||||
bool pressed = lua_tool_button("B", std::to_string(id));
|
||||
|
||||
SetCursorScreenPos(ImVec2(rect.Max.x - SCALE(180), rect.Min.y + SCALE(23)));
|
||||
if (lua_tool_button("C", std::to_string(id)))
|
||||
var->c_lua.data.erase(var->c_lua.data.begin() + lua_id);
|
||||
|
||||
SetCursorScreenPos(stored_cursor_pos);
|
||||
|
||||
return pressed;
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
#include "../settings/functions.h"
|
||||
|
||||
void c_notify::add_notify(std::string_view text, float notify_delay, notify_position type)
|
||||
{
|
||||
notifications.push_back({ notify_count++, text, notify_delay, 0.f, 0.f, 0.f, true, type });
|
||||
}
|
||||
|
||||
void c_notify::setup_notify()
|
||||
{
|
||||
const float speed = 4.f;
|
||||
|
||||
int cur_notify_value = 0;
|
||||
for (int i = 0; i < notifications.size(); ++i)
|
||||
{
|
||||
auto& notification = notifications[i];
|
||||
|
||||
if (notification.active_notify)
|
||||
notification.notify_timer += speed * ImGui::GetIO().DeltaTime;
|
||||
|
||||
if (notification.notify_timer >= notification.notify_delay) notification.active_notify = false;
|
||||
|
||||
notification.notify_alpha = ImClamp(notification.notify_alpha + (gui->fixed_speed(4.f) * (notification.active_notify ? 1.f : -1.f)), 0.f, 1.f);
|
||||
|
||||
notification.notify_offset = easing->im_ease(i, notification.active_notify, -(CalcTextSize(notification.text.data()).x + SCALE(120)), SCALE(20.f), gui->fixed_speed(14.f), back);
|
||||
|
||||
if (notification.notify_alpha <= 0.f && !notification.active_notify) cur_notify_value--;
|
||||
|
||||
render_notify(cur_notify_value, notification.notify_alpha, notification.notify_offset, notification.notify_timer, notification.notify_delay, notification.text, notification.type);
|
||||
cur_notify_value++;
|
||||
}
|
||||
}
|
||||
|
||||
void c_notify::render_notify(int notification_index, float notification_alpha, float notification_offset, float notification_duration, float notification_delay, std::string_view notification_text, notify_position notification_position)
|
||||
{
|
||||
float font_width = set->c_font.inter_medium[1]->CalcTextSizeA(set->c_font.inter_medium[1]->FontSize, FLT_MAX, -1, notification_text.data()).x;
|
||||
float percent_remaining = (notification_duration / notification_delay) * 100;
|
||||
|
||||
int padding_x = SCALE(20);
|
||||
int padding_y = SCALE(80);
|
||||
|
||||
if (percent_remaining < 20) notification_alpha *= percent_remaining / 20;
|
||||
|
||||
gui->set_next_window_size(ImVec2(padding_x + font_width, SCALE(60)));
|
||||
|
||||
ImVec2 position;
|
||||
switch (notification_position)
|
||||
{
|
||||
case top_left:
|
||||
position = ImVec2(notification_offset, padding_x + notification_index * padding_y);
|
||||
break;
|
||||
case top_right:
|
||||
position = ImVec2(GetIO().DisplaySize.x - ((font_width + padding_x) + notification_offset), padding_x + notification_index * padding_y);
|
||||
break;
|
||||
case bottom_left:
|
||||
position = ImVec2(notification_offset, (GetIO().DisplaySize.y - padding_y) - notification_index * padding_y);
|
||||
break;
|
||||
case bottom_right:
|
||||
position = ImVec2(GetIO().DisplaySize.x - ((font_width + padding_x) + notification_offset), (GetIO().DisplaySize.y - padding_y) - notification_index * padding_y);
|
||||
break;
|
||||
}
|
||||
|
||||
static float notification_y_offset[250] = { 0.0f };
|
||||
notification_y_offset[notification_index] = ImLerp(notification_y_offset[notification_index], (percent_remaining < 20) ? (1.0f - (percent_remaining / 20.0f)) * padding_y : 0.0f, gui->fixed_speed(15.0f));
|
||||
position.y += notification_y_offset[notification_index];
|
||||
|
||||
gui->set_next_window_pos(position);
|
||||
|
||||
gui->push_style_var(ImGuiStyleVar_Alpha, notification_alpha);
|
||||
|
||||
gui->begin((std::stringstream() << "notify" << notification_index).str(), nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoMove);
|
||||
{
|
||||
const ImVec2 position = ImGui::GetWindowPos();
|
||||
const ImVec2 content_region = ImGui::GetContentRegionMax();
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
ImGuiStyle* gui_style = &ImGui::GetStyle();
|
||||
|
||||
{ // style
|
||||
gui_style->WindowPadding = { 0, 0 };
|
||||
gui_style->ItemSpacing = SCALE(20, 20);
|
||||
gui_style->WindowBorderSize = { 0 };
|
||||
gui_style->WindowRounding = SCALE(4.f);
|
||||
}
|
||||
|
||||
{ // decorations
|
||||
draw->add_rect_filled(draw_list, { position.x, position.y }, position + content_region, gui->get_clr(clr->c_window.layout), gui_style->WindowRounding);
|
||||
draw->render_text(draw_list, set->c_font.inter_medium[1], { position.x + SCALE(10), position.y }, { position.x + CalcTextSize(notification_text.data()).x + SCALE(60), position.y + SCALE(40) }, gui->get_clr(clr->c_text.text_active), notification_text.data(), NULL, NULL, { 0.0, 0.5 }, NULL);
|
||||
|
||||
draw->add_rect_filled(draw_list, { position.x + SCALE(10), position.y + (content_region.y - SCALE(15)) }, { position.x + content_region.x - SCALE(10), position.y + (content_region.y - SCALE(10)) }, gui->get_clr(clr->c_element.layout), SCALE((10.f)));
|
||||
draw->add_rect_filled(draw_list, { position.x + SCALE(10), position.y + (content_region.y - SCALE(15)) }, { position.x + SCALE(20) + (content_region.x - SCALE(30)) * percent_remaining / 100, position.y + (content_region.y - SCALE(10)) }, gui->get_clr(clr->c_other_clr.accent_clr), SCALE(10.f));
|
||||
}
|
||||
}
|
||||
gui->end();
|
||||
|
||||
gui->pop_style_var();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#include "../settings/functions.h"
|
||||
|
||||
bool c_widget::selection(std::string_view label, const ImVec2& size, int selection_id, int& selection_variable)
|
||||
{
|
||||
struct selection_state
|
||||
{
|
||||
ImVec4 background;
|
||||
ImVec4 text;
|
||||
};
|
||||
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems) return false;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label.data());
|
||||
|
||||
const bool selected = selection_id == selection_variable;
|
||||
const float label_size = CalcTextSize(label.data(), NULL, true).x;
|
||||
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
ImRect rect(pos, pos + SCALE(size));
|
||||
|
||||
ItemSize(rect, 0);
|
||||
if (!ItemAdd(rect, id)) return false;
|
||||
|
||||
bool hovered, held, pressed = ButtonBehavior(rect, id, &hovered, &held);
|
||||
if (pressed) selection_variable = selection_id;
|
||||
|
||||
selection_state* state = gui->anim_container(&state, id);
|
||||
|
||||
state->background = ImLerp(state->background, selected ? clr->c_element.dropdown_selection_layout : clr->c_element.layout, gui->fixed_speed(12.f));
|
||||
state->text = ImLerp(state->text, selected ? clr->c_other_clr.accent_clr : clr->c_text.text, gui->fixed_speed(12.f));
|
||||
|
||||
draw->render_text(window->DrawList, set->c_font.icon[6], rect.Min - SCALE(12, 12), rect.Max + SCALE(12, 12), gui->get_clr(clr->c_child.layout), "A", NULL, NULL, ImVec2(0.5f, 0.5f));
|
||||
draw->render_text(window->DrawList, set->c_font.icon[5], rect.Min - SCALE(1, 0), rect.Max - SCALE(1, 0), gui->get_clr(state->background), "A", NULL, NULL, ImVec2(0.5f, 0.5f));
|
||||
draw->render_text(window->DrawList, set->c_font.icon[1], rect.Min, rect.Max, gui->get_clr(state->text), label.data(), 0, 0, { 0.5, 0.5 });
|
||||
|
||||
return pressed;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,570 @@
|
||||
#include "settings/functions.h"
|
||||
#include "shader/blur.hpp"
|
||||
|
||||
void c_gui::render()
|
||||
{
|
||||
|
||||
gui->new_frame();
|
||||
{
|
||||
notify->setup_notify();
|
||||
|
||||
draw->add_image(GetBackgroundDrawList(), set->c_texture.bg, { 0, 0 }, { 1920, 1080 }, { 0, 0 }, { 1, 1 }, gui->get_clr(clr->c_other_clr.white_clr));
|
||||
|
||||
gui->set_next_window_size(SCALE(set->c_window.window_size));
|
||||
|
||||
gui->begin({ "NAME" }, { 0 }, set->c_window.window_flags);
|
||||
{
|
||||
const ImVec2 pos = GetWindowPos();
|
||||
const ImVec2 size = GetWindowSize();
|
||||
|
||||
ImDrawList* draw_list = GetWindowDrawList();
|
||||
ImGuiStyle* style = &GetStyle();
|
||||
|
||||
{
|
||||
style->WindowBorderSize = SCALE(set->c_window.border_size);
|
||||
style->WindowRounding = SCALE(set->c_window.rounding);
|
||||
style->WindowPadding = SCALE(set->c_window.padding);
|
||||
|
||||
style->ScrollbarSize = SCALE(set->c_window.scrollbar_size);
|
||||
style->ItemSpacing = SCALE(set->c_window.item_spacing);
|
||||
}
|
||||
|
||||
draw_background_blur(draw_list, g_pSwapChain, g_pd3dDevice, g_pd3dDeviceContext, GetWindowPos(), GetWindowPos() + GetWindowSize(), style->WindowRounding);
|
||||
|
||||
draw->add_rect_filled(draw_list, { pos.x, pos.y }, { pos.x + size.x, pos.y + size.y }, gui->get_clr(clr->c_window.general_layout), SCALE(set->c_window.general_rounding));
|
||||
draw->add_rect(draw_list, { pos.x, pos.y }, { pos.x + size.x, pos.y + size.y }, gui->get_clr(clr->c_window.general_stroke), SCALE(set->c_window.general_rounding));
|
||||
|
||||
draw->add_rect_filled(draw_list, { pos.x + SCALE(110), pos.y + SCALE(15) }, { pos.x + (size.x - SCALE(15)), pos.y + (size.y - SCALE(15)) }, gui->get_clr(clr->c_window.layout), SCALE(set->c_window.rounding));
|
||||
draw->add_rect(draw_list, { pos.x + SCALE(110), pos.y + SCALE(15) }, { pos.x + (size.x - SCALE(15)), pos.y + (size.y - SCALE(15)) }, gui->get_clr(clr->c_window.stroke), SCALE(set->c_window.rounding));
|
||||
|
||||
draw->rect_filled_multi_color(draw_list, { pos.x + size.x / 2, pos.y }, { pos.x + size.x, pos.y + 1 }, gui->get_clr(clr->c_other_clr.accent_clr, 0.2f), gui->get_clr(clr->c_other_clr.accent_clr, 0.f), gui->get_clr(clr->c_other_clr.accent_clr, 0.f), gui->get_clr(clr->c_other_clr.accent_clr, 0.2f));
|
||||
draw->rect_filled_multi_color(draw_list, { pos.x, pos.y }, { pos.x + size.x / 2, pos.y + 1 }, gui->get_clr(clr->c_other_clr.accent_clr, 0.f), gui->get_clr(clr->c_other_clr.accent_clr, 0.2f), gui->get_clr(clr->c_other_clr.accent_clr, 0.2f), gui->get_clr(clr->c_other_clr.accent_clr, 0.f));
|
||||
|
||||
draw->rect_filled_multi_color(draw_list, { pos.x + size.x / 2, pos.y + size.y - 1 }, { pos.x + size.x, pos.y + size.y }, gui->get_clr(clr->c_other_clr.accent_clr, 0.2f), gui->get_clr(clr->c_other_clr.accent_clr, 0.f), gui->get_clr(clr->c_other_clr.accent_clr, 0.f), gui->get_clr(clr->c_other_clr.accent_clr, 0.2f));
|
||||
draw->rect_filled_multi_color(draw_list, { pos.x, pos.y + size.y - 1 }, { pos.x + size.x / 2, pos.y + size.y }, gui->get_clr(clr->c_other_clr.accent_clr, 0.f), gui->get_clr(clr->c_other_clr.accent_clr, 0.2f), gui->get_clr(clr->c_other_clr.accent_clr, 0.2f), gui->get_clr(clr->c_other_clr.accent_clr, 0.f));
|
||||
|
||||
draw->render_text(draw_list, set->c_font.icon[2], { pos.x, pos.y }, { pos.x + SCALE(110), pos.y + size.y }, gui->get_clr(clr->c_other_clr.accent_clr), "B", 0, 0, { 0.5, 0.5 });
|
||||
|
||||
gui->push_font(set->c_font.name);
|
||||
|
||||
const int vtx_start_one = draw_list->VtxBuffer.Size;
|
||||
gui->rotate_start();
|
||||
draw->render_text_with_spacing(set->c_window.name.c_str(), SCALE(3.f), pos, pos + ImVec2(SCALE(110), size.y / 2), ImColor(255, 255, 255), true);
|
||||
gui->rotate_end(gui->deg_to_rad(-90));
|
||||
const int vtx_end_one = draw_list->VtxBuffer.Size;
|
||||
draw->set_linear_color_alpha(draw_list, vtx_start_one, vtx_end_one, pos + ImVec2(0, size.y / 6), pos + ImVec2(0, size.y / 2), gui->get_clr(clr->c_other_clr.accent_clr, 0.f), gui->get_clr(clr->c_other_clr.accent_clr));
|
||||
|
||||
const int vtx_start_two = draw_list->VtxBuffer.Size;
|
||||
draw->render_text_with_spacing(set->c_window.name.c_str(), SCALE(3.f), pos + ImVec2(0, size.y / 2), pos + ImVec2(SCALE(110), size.y), ImColor(255, 255, 255), true);
|
||||
const int vtx_end_two = draw_list->VtxBuffer.Size;
|
||||
draw->set_linear_color_alpha(draw_list, vtx_start_two, vtx_end_two, pos + ImVec2(0, size.y / 2), pos + ImVec2(0, size.y / 2 + size.y / 3), gui->get_clr(clr->c_other_clr.accent_clr), gui->get_clr(clr->c_other_clr.accent_clr, 0.f));
|
||||
|
||||
gui->pop_font();
|
||||
|
||||
gui->set_cursor_pos(SCALE(110, 15));
|
||||
|
||||
var->c_selection.selection_alpha = ImClamp(var->c_selection.selection_alpha + (4.f * ImGui::GetIO().DeltaTime * (var->c_selection.selection == var->c_selection.selection_active ? 1.f : -1.f)), 0.f, 1.f);
|
||||
if (var->c_selection.selection_alpha == 0.f && var->c_selection.selection_add == 0.f) var->c_selection.selection_active = var->c_selection.selection;
|
||||
|
||||
gui->push_style_var(ImGuiStyleVar_Alpha, var->c_selection.selection_alpha * style->Alpha);
|
||||
|
||||
gui->begin_content("content", GetContentRegionAvail() - SCALE(15, 15), { 15, 15 }, { 15, 15 });
|
||||
{
|
||||
if (var->c_selection.selection_active == 0)
|
||||
{
|
||||
gui->begin_group();
|
||||
{
|
||||
|
||||
gui->begin_child("ragebot");
|
||||
{
|
||||
|
||||
if (widget->checkbox_with_key("Enable ragebot", &var->c_ragebot.ragebot, &var->c_ragebot.rage_key, &var->c_ragebot.rage_holding, &var->c_ragebot.rage_value, &var->c_ragebot.rage_show_binds))
|
||||
{
|
||||
notify->add_notify("You have successfully summoned a notification!", 15, static_cast<notify_position>(var->c_notify.notify_position));
|
||||
};
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox("Silent aimbot", &var->c_ragebot.silent_aimbot);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox("Hit chance", &var->c_ragebot.hit_chance);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->slider_int("Field of view", &var->c_ragebot.fov, -180, 180, 1, "%d\xC2\xB0");
|
||||
}
|
||||
gui->end_child();
|
||||
|
||||
gui->begin_child("other");
|
||||
{
|
||||
|
||||
widget->dropdown("Body aimbot", &var->c_other.body_selection, var->c_other.body_list, var->c_other.body_list.size());
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->dropdown("Safe points", &var->c_other.points_selection, var->c_other.points_list, var->c_other.points_list.size());
|
||||
|
||||
}
|
||||
gui->end_child();
|
||||
|
||||
gui->begin_child("recoil");
|
||||
{
|
||||
|
||||
widget->checkbox_with_key("Enable recoil", &var->c_recoil.enable_recoil, &var->c_recoil.recoil_key, &var->c_recoil.recoil_holding, &var->c_recoil.recoil_value, &var->c_recoil.recoil_show_binds);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->slider_int("Smoothness", &var->c_recoil.smoothness, 0, 100, 1, "%d%%");
|
||||
|
||||
}
|
||||
gui->end_child();
|
||||
|
||||
}
|
||||
gui->end_group();
|
||||
|
||||
gui->sameline();
|
||||
|
||||
gui->begin_group();
|
||||
{
|
||||
|
||||
gui->begin_child("move");
|
||||
{
|
||||
|
||||
widget->slider_int("Hit chance", &var->c_move.hit_chance, 0, 100, 1, "%d%%");
|
||||
{
|
||||
widget->set_tooltip("Hit chance", "It displays a tooltip when you hover over an item, a very handy GUI utility\nwith many functions that are not always easy to understand by name.");
|
||||
}
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->slider_int("Max misses", &var->c_move.max_misses, 0, 100, 1, "%d%%");
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox_with_key("Static point scale", &var->c_move.point_scale, &var->c_move.point_key, &var->c_move.point_holding, &var->c_move.point_value, &var->c_move.point_show_binds);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox("Head safety if lethal", &var->c_move.head_safety);
|
||||
|
||||
}
|
||||
gui->end_child();
|
||||
|
||||
gui->begin_child("trigger");
|
||||
{
|
||||
|
||||
widget->checkbox_with_key("Enable triggerbot", &var->c_trigger.enable_trigger, &var->c_trigger.trigger_key, &var->c_trigger.trigger_holding, &var->c_trigger.trigger_value, &var->c_trigger.trigger_show_binds);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox("Enable trigger in smoke", &var->c_trigger.trigger_in_smoke);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->button("Button", { GetContentRegionAvail().x, SCALE(35) });
|
||||
|
||||
}
|
||||
gui->end_child();
|
||||
|
||||
gui->begin_child("settings");
|
||||
{
|
||||
|
||||
widget->slider_float("Pitch", &var->c_settings.pitch, 0.f, 1.f, 0.1f, "%.3f");
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->slider_float("Yaw", &var->c_settings.yaw, 0.f, 1.f, 0.1f, "%.3f");
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox_with_key("Static point scale", &var->c_settings.point_scale, &var->c_settings.point_key, &var->c_settings.point_holding, &var->c_settings.point_value, &var->c_settings.point_show_binds);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox("Head safety if lethal", &var->c_settings.head_safety);
|
||||
}
|
||||
gui->end_child();
|
||||
|
||||
}
|
||||
gui->end_group();
|
||||
}
|
||||
else if (var->c_selection.selection_active == 3)
|
||||
{
|
||||
gui->begin_group();
|
||||
{
|
||||
|
||||
gui->begin_child("esp");
|
||||
{
|
||||
widget->checkbox_with_key("Enable ESP", &var->c_esp.esp, &var->c_esp.esp_key, &var->c_esp.esp_holding, &var->c_esp.esp_value, &var->c_esp.esp_show_binds);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox("Through walls", &var->c_esp.through_walls);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->dropdown("Dynamic tracer", &var->c_esp.tracers_selection, var->c_esp.tracers_list, var->c_esp.tracers_list.size());
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox("Dynamic boxes", &var->c_esp.dynamic_boxes);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox_with_color("In-Game radar", &var->c_esp.ingame_radar, var->c_esp.inagame_color, true);
|
||||
}
|
||||
gui->end_child();
|
||||
|
||||
gui->begin_child("glow");
|
||||
{
|
||||
widget->checkbox_with_key("Enable glow", &var->c_glow.glow, &var->c_glow.glow_key, &var->c_glow.glow_holding, &var->c_glow.glow_value, &var->c_glow.glow_show_binds);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->slider_int("The power of brightness", &var->c_glow.power, 0, 100, 1, "%d%$");
|
||||
}
|
||||
gui->end_child();
|
||||
|
||||
gui->begin_child("attachments");
|
||||
{
|
||||
widget->checkbox_with_color("Attachments", &var->c_attachments.attachments, var->c_attachments.attachments_color, true);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox_with_key("Visible teammates", &var->c_attachments.teammates, &var->c_attachments.teammates_key, &var->c_attachments.teammates_holding, &var->c_attachments.teammates_value, &var->c_attachments.teammates_show_binds);
|
||||
}
|
||||
gui->end_child();
|
||||
|
||||
}
|
||||
gui->end_group();
|
||||
|
||||
gui->sameline();
|
||||
|
||||
gui->begin_group();
|
||||
{
|
||||
|
||||
gui->begin_child("chams");
|
||||
{
|
||||
widget->checkbox_with_key("Enable chams", &var->c_chams.chams, &var->c_chams.chams_key, &var->c_chams.chams_holding, &var->c_chams.chams_value, &var->c_chams.chams_show_binds);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox_with_color("Backtrack", &var->c_chams.backtrack, var->c_chams.backtrack_color, true);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox_with_color("On shot", &var->c_chams.onshot, var->c_chams.onshot_color, true);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox_with_color("Ragdolls", &var->c_chams.ragdolls, var->c_chams.ragdolls_color, true);
|
||||
|
||||
}
|
||||
gui->end_child();
|
||||
|
||||
gui->begin_child("skeleton");
|
||||
{
|
||||
widget->checkbox("Skeleton", &var->c_skeleton.skeleton);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->dropdown("Snaplines", &var->c_skeleton.snaplines_selection, var->c_skeleton.snaplines_list, var->c_skeleton.snaplines_list.size());
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox_with_color("Weapon", &var->c_skeleton.weapon, var->c_skeleton.weapon_color, true);
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->checkbox_with_color("Nickname", &var->c_skeleton.nickname, var->c_skeleton.nickname_color, true);
|
||||
}
|
||||
gui->end_child();
|
||||
|
||||
}
|
||||
gui->end_group();
|
||||
}
|
||||
else if (var->c_selection.selection_active == 4)
|
||||
{
|
||||
|
||||
draw->add_line(GetWindowDrawList(), GetWindowPos() + ImVec2(GetStyle().WindowPadding.x, SCALE(64)), GetWindowPos() + ImVec2(GetWindowWidth() - GetStyle().WindowPadding.x, SCALE(64)), gui->get_clr(clr->c_child.stroke), SCALE(1.f));
|
||||
|
||||
widget->tool_dropdown("Sort", &var->c_lua.sort_selection, var->c_lua.sort_list, var->c_lua.sort_list.size());
|
||||
|
||||
gui->sameline();
|
||||
|
||||
if (widget->tool_button("Create", "A", SCALE(90, 36)))
|
||||
var->c_lua.create = true;
|
||||
|
||||
if (var->c_lua.create)
|
||||
{
|
||||
gui->set_next_window_size(SCALE(310, 80));
|
||||
gui->set_next_window_pos(GetWindowPos() + (GetWindowSize() / 2 - SCALE(310, 80) / 2));
|
||||
gui->push_style_var(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
gui->begin("Create", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground);
|
||||
{
|
||||
draw->add_rect_filled(GetWindowDrawList(), GetWindowPos(), GetWindowPos() + GetWindowSize(), gui->get_clr(clr->c_child.layout), SCALE(set->c_child.rounding));
|
||||
draw->add_rect(GetWindowDrawList(), GetWindowPos(), GetWindowPos() + GetWindowSize(), gui->get_clr(clr->c_child.stroke), SCALE(set->c_child.rounding), 0, SCALE(1.f));
|
||||
|
||||
gui->set_cursor_pos(SCALE(20, 20));
|
||||
gui->begin_group();
|
||||
{
|
||||
widget->text_field("Lua Name", "M", var->c_lua.name, 128, SCALE(180, 40));
|
||||
gui->sameline();
|
||||
ImGui::PushID("Create Lua");
|
||||
if (widget->button("Create", SCALE(75, 40)))
|
||||
{
|
||||
std::string name(var->c_lua.name);
|
||||
var->c_lua.data.insert(var->c_lua.data.begin(), { name, gui->get_current_date(), false });
|
||||
var->c_lua.create = false;
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
gui->end_group();
|
||||
|
||||
if (!IsMouseHoveringRect(GetWindowPos(), GetWindowPos() + GetWindowSize()) && (IsMouseClicked(0) || IsMouseClicked(1)))
|
||||
var->c_lua.create = false;
|
||||
|
||||
}
|
||||
gui->end();
|
||||
gui->pop_style_var();
|
||||
}
|
||||
|
||||
gui->set_cursor_pos_y(SCALE(80));
|
||||
gui->begin_group();
|
||||
{
|
||||
for (int i = 0; i < var->c_lua.data.size(); i++)
|
||||
{
|
||||
if (var->c_lua.sort_selection == 0)
|
||||
{
|
||||
if (widget->lua_selectable(&var->c_lua.data.at(i), i))
|
||||
{
|
||||
var->c_lua.editable = var->c_lua.data.at(i).name;
|
||||
var->c_lua.opened = true;
|
||||
}
|
||||
}
|
||||
else if (var->c_lua.sort_selection == 1)
|
||||
{
|
||||
if (widget->lua_selectable(&var->c_lua.data.at(var->c_lua.data.size() - i - 1), i))
|
||||
{
|
||||
var->c_lua.editable = var->c_lua.data.at(i).name;
|
||||
var->c_lua.opened = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
gui->end_group();
|
||||
|
||||
if (var->c_lua.opened)
|
||||
{
|
||||
gui->set_next_window_size(SCALE(500, 520));
|
||||
gui->set_next_window_pos(pos + ImVec2(size.x + SCALE(20), 0));
|
||||
gui->push_style_var(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
gui->begin("Text Editor", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground);
|
||||
{
|
||||
draw->add_rect_filled(GetWindowDrawList(), GetWindowPos(), GetWindowPos() + GetWindowSize(), gui->get_clr(clr->c_window.general_layout), SCALE(set->c_window.rounding));
|
||||
draw->add_rect(GetWindowDrawList(), GetWindowPos(), GetWindowPos() + GetWindowSize(), gui->get_clr(clr->c_window.general_stroke), SCALE(set->c_window.rounding), 0, SCALE(1.f));
|
||||
draw->add_line(GetWindowDrawList(), GetWindowPos() + SCALE(0, 40), GetWindowPos() + ImVec2(GetWindowSize().x, SCALE(40)), gui->get_clr(clr->c_window.general_stroke), SCALE(1.f));
|
||||
draw->add_line(GetWindowDrawList(), GetWindowPos() + ImVec2(0, GetWindowSize().y - SCALE(40)), GetWindowPos() + ImVec2(GetWindowSize().x, GetWindowSize().y - SCALE(40)), gui->get_clr(clr->c_window.general_stroke), SCALE(1.f));
|
||||
draw->render_text(GetWindowDrawList(), set->c_font.inter_medium[0], GetWindowPos() + SCALE(40, 0), GetWindowPos() + ImVec2(GetWindowWidth(), SCALE(40)), gui->get_clr(clr->c_text.text_active), (std::stringstream{} << "Lua Editor - " << var->c_lua.editable).str().c_str(), NULL, NULL, ImVec2(0.f, 0.5f));
|
||||
draw->render_text(GetWindowDrawList(), set->c_font.icon[4], GetWindowPos() + SCALE(15, 1), GetWindowPos() + ImVec2(GetWindowWidth(), SCALE(40)), gui->get_clr(clr->c_other_clr.accent_clr), "B", NULL, NULL, ImVec2(0.f, 0.5f));
|
||||
|
||||
gui->set_cursor_pos(ImVec2(GetWindowWidth() - SCALE(30), 13));
|
||||
if (widget->lua_tool_button("E", "Close Button"))
|
||||
var->c_lua.opened = false;
|
||||
|
||||
gui->set_cursor_pos(SCALE(10, 50));
|
||||
text_editor->render("Text Editor", SCALE(480, 420));
|
||||
|
||||
gui->set_cursor_pos(GetWindowSize() - SCALE(122, 34));
|
||||
if (widget->tool_button("Save", "", SCALE(54, 28)))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
gui->set_cursor_pos(GetWindowSize() - SCALE(61, 34));
|
||||
if (widget->tool_button("Run", "", SCALE(54, 28)))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
gui->end();
|
||||
gui->pop_style_var();
|
||||
}
|
||||
}
|
||||
else if (var->c_selection.selection_active == 5)
|
||||
{
|
||||
|
||||
draw->add_line(GetWindowDrawList(), GetWindowPos() + ImVec2(GetStyle().WindowPadding.x, SCALE(64)), GetWindowPos() + ImVec2(GetWindowWidth() - GetStyle().WindowPadding.x, SCALE(64)), gui->get_clr(clr->c_child.stroke), SCALE(1.f));
|
||||
widget->tool_dropdown("Sort", &var->c_config.sort_selection, var->c_config.sort_list, var->c_config.sort_list.size());
|
||||
|
||||
gui->sameline();
|
||||
|
||||
if (widget->tool_button("Create", "A", SCALE(90, 36)))
|
||||
var->c_config.create = true;
|
||||
|
||||
if (var->c_config.create)
|
||||
{
|
||||
gui->set_next_window_size(SCALE(310, 80));
|
||||
gui->set_next_window_pos(GetWindowPos() + (GetWindowSize() / 2 - SCALE(310, 80) / 2));
|
||||
gui->push_style_var(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
gui->begin("Create", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground);
|
||||
{
|
||||
draw->add_rect_filled(GetWindowDrawList(), GetWindowPos(), GetWindowPos() + GetWindowSize(), gui->get_clr(clr->c_child.layout), SCALE(set->c_child.rounding));
|
||||
draw->add_rect(GetWindowDrawList(), GetWindowPos(), GetWindowPos() + GetWindowSize(), gui->get_clr(clr->c_child.stroke), SCALE(set->c_child.rounding), 0, SCALE(1.f));
|
||||
|
||||
gui->set_cursor_pos(SCALE(20, 20));
|
||||
gui->begin_group();
|
||||
{
|
||||
widget->text_field("Config Name", "M", var->c_config.name, 128, SCALE(180, 40));
|
||||
gui->sameline();
|
||||
ImGui::PushID("Create Config");
|
||||
if (widget->button("Create", SCALE(75, 40)))
|
||||
{
|
||||
std::string name(var->c_config.name);
|
||||
var->c_config.data.insert(var->c_config.data.begin(), { name, gui->get_current_date() });
|
||||
var->c_config.create = false;
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
gui->end_group();
|
||||
|
||||
if (!IsMouseHoveringRect(GetWindowPos(), GetWindowPos() + GetWindowSize()) && (IsMouseClicked(0) || IsMouseClicked(1)))
|
||||
var->c_config.create = false;
|
||||
|
||||
}
|
||||
gui->end();
|
||||
gui->pop_style_var();
|
||||
}
|
||||
|
||||
gui->set_cursor_pos_y(SCALE(80));
|
||||
gui->begin_group();
|
||||
{
|
||||
for (int i = 0; i < var->c_config.data.size(); i++)
|
||||
{
|
||||
if (var->c_config.sort_selection == 0)
|
||||
widget->config_selectable(&var->c_config.data.at(i), i, var->c_config.active);
|
||||
else if (var->c_config.sort_selection == 1)
|
||||
widget->config_selectable(&var->c_config.data.at(var->c_config.data.size() - i - 1), var->c_config.data.size() - i - 1, var->c_config.active);
|
||||
}
|
||||
}
|
||||
gui->end_group();
|
||||
}
|
||||
else if (var->c_selection.selection_active == 6)
|
||||
{
|
||||
gui->begin_group();
|
||||
{
|
||||
|
||||
gui->begin_child("oth");
|
||||
{
|
||||
static char buf[128];
|
||||
widget->text_field("Enter your text", "M", buf, 128, { GetContentRegionAvail().x, SCALE(35) });
|
||||
|
||||
widget->separator();
|
||||
|
||||
widget->button("Button", { GetContentRegionAvail().x, SCALE(35) });
|
||||
|
||||
widget->separator();
|
||||
|
||||
const float width = GetContentRegionAvail().x;
|
||||
|
||||
widget->button("Press", { (width - style->ItemSpacing.x) / 2, SCALE(35) });
|
||||
|
||||
gui->sameline();
|
||||
|
||||
widget->button("Click", { (width - style->ItemSpacing.x) / 2, SCALE(35) });
|
||||
}
|
||||
gui->end_child();
|
||||
|
||||
}
|
||||
gui->end_group();
|
||||
|
||||
gui->sameline();
|
||||
|
||||
gui->begin_group();
|
||||
{
|
||||
|
||||
gui->begin_child("dpi");
|
||||
{
|
||||
widget->slider_int("DPI", &var->c_dpi.dpi_saved, 100, 200, 1, "%d%%");
|
||||
|
||||
if (var->c_dpi.dpi != var->c_dpi.dpi_saved / 100.f && IsMouseReleased(ImGuiMouseButton_Left)) {
|
||||
|
||||
notify->add_notify("You have successfully set the menu size", 15, static_cast<notify_position>(var->c_notify.notify_position));
|
||||
var->c_dpi.dpi_changed = true;
|
||||
|
||||
}
|
||||
}
|
||||
gui->end_child();
|
||||
|
||||
}
|
||||
gui->end_group();
|
||||
}
|
||||
}
|
||||
gui->end_content();
|
||||
|
||||
gui->pop_style_var(2);
|
||||
|
||||
}
|
||||
gui->end();
|
||||
|
||||
gui->push_style_var(ImGuiStyleVar_WindowPadding, SCALE(15, 15));
|
||||
gui->push_style_var(ImGuiStyleVar_ItemSpacing, SCALE(4, 0));
|
||||
{
|
||||
gui->set_next_window_pos(SCALE(20, 20));
|
||||
gui->begin({ "SELECTION" }, { 0 }, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_AlwaysAutoResize);
|
||||
{
|
||||
const ImVec2 pos = GetWindowPos();
|
||||
const ImVec2 size = GetWindowSize();
|
||||
|
||||
ImDrawList* draw_list = GetBackgroundDrawList();
|
||||
|
||||
gui->set_cursor_pos_x(SCALE(54));
|
||||
gui->begin_group();
|
||||
{
|
||||
widget->selection(var->c_selection.selection_icon[0].data(), ImVec2(74, 76), 0, var->c_selection.selection);
|
||||
|
||||
gui->sameline();
|
||||
|
||||
widget->selection(var->c_selection.selection_icon[1].data(), ImVec2(74, 76), 1, var->c_selection.selection);
|
||||
}
|
||||
gui->end_group();
|
||||
|
||||
gui->set_cursor_pos_y(get_cursor_pos_y() - SCALE(5));
|
||||
gui->begin_group();
|
||||
{
|
||||
widget->selection(var->c_selection.selection_icon[2].data(), ImVec2(74, 76), 2, var->c_selection.selection);
|
||||
|
||||
gui->sameline();
|
||||
|
||||
widget->selection(var->c_selection.selection_icon[3].data(), ImVec2(74, 76), 3, var->c_selection.selection);
|
||||
|
||||
gui->sameline();
|
||||
|
||||
widget->selection(var->c_selection.selection_icon[4].data(), ImVec2(74, 76), 4, var->c_selection.selection);
|
||||
}
|
||||
gui->end_group();
|
||||
|
||||
gui->set_cursor_pos(get_cursor_pos() + SCALE(39, -5));
|
||||
gui->begin_group();
|
||||
{
|
||||
widget->selection(var->c_selection.selection_icon[5].data(), ImVec2(74, 76), 5, var->c_selection.selection);
|
||||
|
||||
gui->sameline();
|
||||
|
||||
widget->selection(var->c_selection.selection_icon[6].data(), ImVec2(74, 76), 6, var->c_selection.selection);
|
||||
}
|
||||
gui->end_group();
|
||||
|
||||
}
|
||||
gui->end();
|
||||
}
|
||||
gui->pop_style_var(2);
|
||||
|
||||
gui->water_mark("watermark", var->c_watermark.watermark_content, static_cast<watermark_position>(var->c_watermark.watermark_position), &var->c_watermark.watermark);
|
||||
|
||||
}
|
||||
gui->end_frame();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,799 @@
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
|
||||
#include "variables.h"
|
||||
#include "elements.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "imgui_impl_dx11.h"
|
||||
#include "imgui_impl_win32.h"
|
||||
|
||||
#include <map>
|
||||
#include <regex>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <array>
|
||||
|
||||
inline ID3D11Device* g_pd3dDevice = nullptr;
|
||||
inline ID3D11DeviceContext* g_pd3dDeviceContext = nullptr;
|
||||
inline IDXGISwapChain* g_pSwapChain = nullptr;
|
||||
inline bool g_SwapChainOccluded = false;
|
||||
inline UINT g_ResizeWidth = 0, g_ResizeHeight = 0;
|
||||
inline ID3D11RenderTargetView* g_mainRenderTargetView = nullptr;
|
||||
|
||||
#define SCALE(...) scale_impl(__VA_ARGS__, var->c_dpi.dpi)
|
||||
|
||||
inline ImVec2 scale_impl(const ImVec2& vec, float dpi) {
|
||||
return ImVec2(roundf(vec.x * dpi), roundf(vec.y * dpi));
|
||||
}
|
||||
|
||||
inline ImVec2 scale_impl(float x, float y, float dpi) {
|
||||
return ImVec2(roundf(x * dpi), roundf(y * dpi));
|
||||
}
|
||||
|
||||
inline float scale_impl(float var, float dpi) {
|
||||
return roundf(var * dpi);
|
||||
}
|
||||
|
||||
#define PI 3.14159265359f
|
||||
|
||||
enum notify_position : int
|
||||
{
|
||||
top_left,
|
||||
top_right,
|
||||
bottom_left,
|
||||
bottom_right,
|
||||
};
|
||||
|
||||
enum fade_direction : int
|
||||
{
|
||||
vertically,
|
||||
horizontally,
|
||||
diagonally,
|
||||
diagonally_reversed,
|
||||
};
|
||||
|
||||
enum watermark_position : int {
|
||||
mark_top_left,
|
||||
mark_top_right,
|
||||
mark_bottom_left,
|
||||
mark_bottom_right,
|
||||
};
|
||||
|
||||
enum interpolation_type {
|
||||
back,
|
||||
elastic,
|
||||
};
|
||||
|
||||
struct lua_data {
|
||||
std::string name;
|
||||
std::string date;
|
||||
bool loaded;
|
||||
};
|
||||
|
||||
struct config_data {
|
||||
std::string name;
|
||||
std::string date;
|
||||
};
|
||||
|
||||
inline D3DX11_IMAGE_LOAD_INFO info;
|
||||
inline ID3DX11ThreadPump* pump{ nullptr };
|
||||
|
||||
using namespace ImGui;
|
||||
|
||||
class c_gui
|
||||
{
|
||||
public:
|
||||
|
||||
template <typename T>
|
||||
T* anim_container(T** state_ptr, ImGuiID id)
|
||||
{
|
||||
T* state = static_cast<T*>(GetStateStorage()->GetVoidPtr(id));
|
||||
if (!state)
|
||||
GetStateStorage()->SetVoidPtr(id, state = new T());
|
||||
|
||||
*state_ptr = state;
|
||||
return state;
|
||||
}
|
||||
|
||||
ImU32 get_clr(const ImVec4& col, float alpha = 1.f);
|
||||
|
||||
float fixed_speed(float speed) { return speed / ImGui::GetIO().Framerate; };
|
||||
|
||||
bool begin(std::string_view name, bool* p_open = nullptr, ImGuiWindowFlags flags = ImGuiWindowFlags_None);
|
||||
|
||||
void end();
|
||||
|
||||
void push_style_color(ImGuiCol idx, ImU32 col);
|
||||
|
||||
void pop_style_color(int count = 1);
|
||||
|
||||
void push_style_var(ImGuiStyleVar idx, float val);
|
||||
|
||||
void push_style_var(ImGuiStyleVar idx, const ImVec2& val);
|
||||
|
||||
void pop_style_var(int count = 1);
|
||||
|
||||
void push_font(ImFont* font);
|
||||
|
||||
void pop_font();
|
||||
|
||||
void set_cursor_pos(const ImVec2& local_pos);
|
||||
|
||||
void set_cursor_pos_x(float x);
|
||||
|
||||
void set_cursor_pos_y(float y);
|
||||
|
||||
ImVec2 get_cursor_pos();
|
||||
|
||||
float get_cursor_pos_x();
|
||||
|
||||
float get_cursor_pos_y();
|
||||
|
||||
void spacing();
|
||||
|
||||
void sameline(float offset_from_start_x = 0.0f, float spacing_w = -1.0f);
|
||||
|
||||
void set_next_window_pos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0, 0));
|
||||
|
||||
void set_next_window_size(const ImVec2& size, ImGuiCond cond = 0);
|
||||
|
||||
void begin_group();
|
||||
|
||||
void end_group();
|
||||
|
||||
bool begin_child(std::string_view name, const ImVec2& size_arg = ImVec2(0, 0), ImGuiChildFlags child_flags = 0, ImGuiWindowFlags window_flags = 0);
|
||||
|
||||
void end_child();
|
||||
|
||||
void begin_content(const char* id, const ImVec2& size_arg, const ImVec2& padding, const ImVec2& spacing);
|
||||
|
||||
void end_content();
|
||||
|
||||
void water_mark(std::string name, std::vector<std::string> function, watermark_position type, bool* visible);
|
||||
|
||||
inline ImGuiWindow* get_current_window() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; };
|
||||
|
||||
void new_frame();
|
||||
|
||||
void end_frame();
|
||||
|
||||
std::string get_current_date();
|
||||
|
||||
void rotate_start();
|
||||
|
||||
void rotate_end(float rad, ImVec2 center = ImVec2(0, 0));
|
||||
|
||||
float deg_to_rad(float deg);
|
||||
|
||||
void render();
|
||||
|
||||
};
|
||||
|
||||
inline c_gui* gui = new c_gui();
|
||||
|
||||
class c_widget
|
||||
{
|
||||
public:
|
||||
|
||||
bool checkbox(std::string_view label, bool* callback);
|
||||
|
||||
bool checkbox_with_key(std::string_view label, bool* callback, int* key, bool* mode, bool* value, bool* show_in_binds);
|
||||
|
||||
bool checkbox_with_color(std::string_view label, bool* callback, float col[4], bool alpha = true);
|
||||
|
||||
bool slider_float(std::string_view label, float* v, float v_min, float v_max, float power = 0.1f, const char* format = "");
|
||||
|
||||
bool slider_int(std::string_view label, int* v, int v_min, int v_max, int power = 1, const char* format = "");
|
||||
|
||||
bool dropdown(std::string_view label, int* current_item, std::vector<std::string>& items, int max_count);
|
||||
|
||||
bool tool_dropdown(std::string_view label, int* current_item, std::vector<std::string>& items, int max_count);
|
||||
|
||||
void multi_dropdown(std::string_view label, bool variable[], std::vector<std::string>& labels, int max_count);
|
||||
|
||||
bool keybind(std::string_view label, int* key);
|
||||
|
||||
bool keybind_button(std::string_view name_id, bool* pressing);
|
||||
|
||||
bool begin_popup(std::string_view name, float size_w, const ImVec2& position = {0, 0});
|
||||
|
||||
void end_popup();
|
||||
|
||||
bool set_tooltip(std::string_view tooltip_id, std::string_view tooltip_text);
|
||||
|
||||
void text_colored(ImFont* font, const ImU32 col, std::string text);
|
||||
|
||||
bool color_edit(std::string_view label, float col[4], ImGuiColorEditFlags flags = 0);
|
||||
|
||||
bool button(std::string_view label, const ImVec2& size);
|
||||
|
||||
bool tool_button(std::string_view label, std::string_view icon, const ImVec2& size);
|
||||
|
||||
bool lua_tool_button(std::string_view icon, std::string_view aid);
|
||||
|
||||
bool text_field(std::string_view hint, std::string_view label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = 0, void* user_data = 0);
|
||||
|
||||
bool selection(std::string_view label, const ImVec2& size, int selection_id, int& selection_variable);
|
||||
|
||||
bool lua_selectable(lua_data* data, int lua_id);
|
||||
|
||||
bool config_selectable(config_data* data, int selection_id, int& selection_variable);
|
||||
|
||||
void separator();
|
||||
|
||||
};
|
||||
|
||||
inline c_widget* widget = new c_widget();
|
||||
|
||||
class c_draw
|
||||
{
|
||||
public:
|
||||
|
||||
void push_clip_rect(ImDrawList* draw, const ImVec2& cr_min, const ImVec2& cr_max, bool intersect_with_current_clip_rect);
|
||||
|
||||
void pop_clip_rect(ImDrawList* draw);
|
||||
|
||||
void add_text(ImDrawList* draw_list, const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = NULL, const ImVec4* cpu_fine_clip_rect = NULL);
|
||||
|
||||
void render_text(ImFont* font, ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, ImU32 color, const char* text, const char* text_display_end = NULL, const ImVec2* text_size_if_known = NULL, const ImVec2& align = { 0.5, 0.5 }, const ImRect* clip_rect = NULL);
|
||||
|
||||
void render_text_with_spacing(const char* text, float spacing, ImVec2 position1, ImVec2 position2, ImU32 color, bool centered);
|
||||
|
||||
void rect_filled_multi_color(ImDrawList* draw, const ImVec2& p_min, const ImVec2& p_max, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left, float rounding = 0.f, ImDrawFlags flags = 0);
|
||||
|
||||
void add_rect_filled(ImDrawList* draw_list, const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0, ImDrawFlags flags = 0);
|
||||
|
||||
void add_circle_filled(ImDrawList* draw_list, const ImVec2& center, float radius, ImU32 col, int num_segments = 0);
|
||||
|
||||
void add_circle(ImDrawList* draw_list, const ImVec2& center, float radius, ImU32 col, int num_segments = 0, float thickness = 0);
|
||||
|
||||
void add_rect(ImDrawList* draw_list, const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags = 0, float tickness = 0);
|
||||
|
||||
void fade_rect_filled(ImDrawList* draw, const ImVec2& pos_min, const ImVec2& pos_max, ImU32 col_one, ImU32 col_two, fade_direction direction, float rounding = 0.f, ImDrawFlags flags = 0);
|
||||
|
||||
void render_text(ImDrawList* draw_list, ImFont* font, const ImVec2& pos_min, const ImVec2& pos_max, ImU32 color, const char* text, const char* text_display_end = NULL, const ImVec2* text_size_if_known = NULL, const ImVec2& align = ImVec2(0.f, 0.f), const ImRect* clip_rect = NULL);
|
||||
|
||||
void radial_gradient(ImDrawList* draw_list, const ImVec2& center, float radius, ImU32 col_in, ImU32 col_out);
|
||||
|
||||
void set_linear_color_alpha(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1);
|
||||
|
||||
void add_image(ImDrawList* draw_list, ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col);
|
||||
|
||||
void add_image_rounded(ImDrawList* draw_list, ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col, float rounding = 0, ImDrawFlags flags = 0);
|
||||
|
||||
void add_line(ImDrawList* draw, const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness = 0);
|
||||
|
||||
};
|
||||
|
||||
inline c_draw* draw = new c_draw();
|
||||
|
||||
struct notify_state
|
||||
{
|
||||
int notify_id;
|
||||
|
||||
std::string_view text;
|
||||
|
||||
float notify_delay;
|
||||
|
||||
float notify_alpha{ 0.f }, notify_offset{ 0.f }, notify_timer{ 0.f };
|
||||
|
||||
bool active_notify{ true };
|
||||
|
||||
notify_position type;
|
||||
};
|
||||
|
||||
class c_notify
|
||||
{
|
||||
public:
|
||||
|
||||
void setup_notify();
|
||||
|
||||
void add_notify(std::string_view text, float notify_delay, notify_position type);
|
||||
|
||||
void render_notify(int cur_notify_value, float notify_alpha, float notify_offset, float notify_percentage, float notify_delay, std::string_view text, notify_position type);
|
||||
|
||||
int notify_count{ 0 };
|
||||
|
||||
std::vector<notify_state> notifications;
|
||||
};
|
||||
|
||||
inline c_notify* notify = new c_notify();
|
||||
|
||||
struct add_item_state
|
||||
{
|
||||
bool window_opened = false;
|
||||
float window_alpha = 0.f;
|
||||
bool window_hovered = false;
|
||||
};
|
||||
|
||||
struct preview_box
|
||||
{
|
||||
ImVec2 position;
|
||||
ImVec2 size;
|
||||
};
|
||||
|
||||
enum preview_area
|
||||
{
|
||||
area_top,
|
||||
area_bottom,
|
||||
area_left,
|
||||
area_right,
|
||||
area_none
|
||||
};
|
||||
|
||||
enum item_position
|
||||
{
|
||||
position_top,
|
||||
position_bottom,
|
||||
position_left,
|
||||
position_right
|
||||
};
|
||||
|
||||
struct item_state
|
||||
{
|
||||
std::string name;
|
||||
ImVec4 color;
|
||||
int position;
|
||||
ImVec2 location;
|
||||
bool swapped;
|
||||
bool active;
|
||||
ImRect rect = ImRect(ImVec2(0, 0), ImVec2(0, 0));
|
||||
};
|
||||
|
||||
class esp_preview
|
||||
{
|
||||
public:
|
||||
|
||||
std::vector<item_state> text =
|
||||
{
|
||||
{ "NICKNAME", ImVec4(1.f, 1.f, 1.f, 1.f), position_top },
|
||||
|
||||
{ "MONEY", ImVec4(1.f, 1.f, 1.f, 1.f), position_right },
|
||||
{ "SCOPE", ImVec4(1.f, 1.f, 1.f, 1.f), position_right },
|
||||
{ "PING", ImVec4(1.f, 1.f, 1.f, 1.f), position_right },
|
||||
{ "KD", ImVec4(1.f, 1.f, 1.f, 1.f), position_right },
|
||||
|
||||
{ "DISTANCE", ImVec4(1.f, 1.f, 1.f, 1.f), position_left },
|
||||
{ "FLASH", ImVec4(1.f, 1.f, 1.f, 1.f), position_left },
|
||||
{ "BLIND", ImVec4(1.f, 1.f, 1.f, 1.f), position_left },
|
||||
{ "LC", ImVec4(1.f, 1.f, 1.f, 1.f), position_left },
|
||||
|
||||
{ "WEAPON", ImVec4(1.f, 1.f, 1.f, 1.f), position_bottom },
|
||||
};
|
||||
|
||||
std::vector<item_state> bar =
|
||||
{
|
||||
{ "HEALTH", ImVec4(132 / 255.f, 255 / 255.f, 152 / 255.f, 1.f), position_left },
|
||||
{ "ARMOR", ImVec4(130 / 255.f, 150 / 255.f, 255 / 255.f, 1.f), position_right },
|
||||
};
|
||||
|
||||
void initialize_preview(const ImVec2& pos, const ImVec2& size, bool render_text, bool render_bar);
|
||||
void render_box(int type);
|
||||
void render_text(item_state& state);
|
||||
void render_bar(item_state& state);
|
||||
|
||||
private:
|
||||
preview_box box;
|
||||
ImRect area_rect[4];
|
||||
|
||||
void fill_box(const ImVec2& pos, const ImVec2& size);
|
||||
void fill_areas();
|
||||
void fill_buffers();
|
||||
|
||||
int texts_buffer[4] = { 0, 0, 0, 0 };
|
||||
int bars_buffer[4] = { 0, 0, 0, 0 };
|
||||
int hovered_area = area_none;
|
||||
|
||||
float area_size = 80.f;
|
||||
};
|
||||
|
||||
inline esp_preview* esp = new esp_preview();
|
||||
|
||||
|
||||
class c_easing
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
float easing_value;
|
||||
|
||||
float ease_in_elastic(float t) { const float c4 = (2 * PI) / 2; return (t <= 0.01f) ? 0.0f : (t >= 0.60f) ? 1.0f : pow(2, -10 * t) * sin((t * 10 - 0.75) * c4) + 1; }
|
||||
|
||||
float ease_in_back(float t) { const float c1 = 1.70158; const float c3 = c1 + 1; return 1 + c3 * pow(t - 1, 3) + c1 * pow(t - 1, 2); }
|
||||
|
||||
struct easing_state {
|
||||
float animTime = 0.0f;
|
||||
bool reverse = false;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T im_ease(int animation_id, bool callback, T min, T max, float speed, interpolation_type type) {
|
||||
easing_state* state = gui->anim_container(&state, GetCurrentWindow()->GetID(animation_id));
|
||||
|
||||
state->animTime = (callback != state->reverse) ? 0.0f : min(state->animTime + 0.1f * speed, 1.0f);
|
||||
state->reverse = callback;
|
||||
|
||||
easing_value = (type == elastic) ? ease_in_elastic(state->animTime) : (type == back) ? ease_in_back(state->animTime) : 0;
|
||||
|
||||
return callback ? easing_value * (max - min) + min : easing_value * (min - max) + max;
|
||||
}
|
||||
|
||||
template <>
|
||||
ImVec2 im_ease<ImVec2>(int animation_id, bool callback, ImVec2 min, ImVec2 max, float speed, interpolation_type type) {
|
||||
easing_state* state = gui->anim_container(&state, GetCurrentWindow()->GetID(animation_id));
|
||||
|
||||
state->animTime = (callback != state->reverse) ? 0.0f : min(state->animTime + 0.1f * speed, 1.0f);
|
||||
state->reverse = callback;
|
||||
|
||||
easing_value = (type == elastic) ? ease_in_elastic(state->animTime) : (type == back) ? ease_in_back(state->animTime) : 0;
|
||||
|
||||
ImVec2 result;
|
||||
result.x = callback ? easing_value * (max.x - min.x) + min.x : easing_value * (min.x - max.x) + max.x;
|
||||
result.y = callback ? easing_value * (max.y - min.y) + min.y : easing_value * (min.y - max.y) + max.y;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
inline std::unique_ptr<c_easing> easing = std::make_unique<c_easing>();
|
||||
|
||||
class c_text_editor
|
||||
{
|
||||
public:
|
||||
enum class pallete_index
|
||||
{
|
||||
def,
|
||||
keyword,
|
||||
number,
|
||||
string,
|
||||
char_literal,
|
||||
punctuation,
|
||||
preprocessor,
|
||||
identifier,
|
||||
known_identifier,
|
||||
preproc_identifier,
|
||||
comment,
|
||||
multi_line_comment,
|
||||
background,
|
||||
cursor,
|
||||
selection,
|
||||
error_marker,
|
||||
breakpoint,
|
||||
line_number,
|
||||
current_line_fill,
|
||||
current_line_fill_inactive,
|
||||
current_line_edge,
|
||||
max
|
||||
};
|
||||
|
||||
enum class selection_mode
|
||||
{
|
||||
normal,
|
||||
word,
|
||||
line
|
||||
};
|
||||
|
||||
struct breakpoint
|
||||
{
|
||||
int m_line;
|
||||
bool m_enabled;
|
||||
std::string m_condition;
|
||||
|
||||
breakpoint()
|
||||
: m_line(-1)
|
||||
, m_enabled(false)
|
||||
{}
|
||||
};
|
||||
|
||||
struct coordinates
|
||||
{
|
||||
int m_line, m_column;
|
||||
coordinates() : m_line(0), m_column(0) {}
|
||||
coordinates(int a_line, int a_column) : m_line(a_line), m_column(a_column)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static coordinates Invalid() { static coordinates invalid(-1, -1); return invalid; }
|
||||
|
||||
bool operator ==(const coordinates& o) const
|
||||
{
|
||||
return
|
||||
m_line == o.m_line &&
|
||||
m_column == o.m_column;
|
||||
}
|
||||
|
||||
bool operator !=(const coordinates& o) const
|
||||
{
|
||||
return
|
||||
m_line != o.m_line ||
|
||||
m_column != o.m_column;
|
||||
}
|
||||
|
||||
bool operator <(const coordinates& o) const
|
||||
{
|
||||
if (m_line != o.m_line)
|
||||
return m_line < o.m_line;
|
||||
return m_column < o.m_column;
|
||||
}
|
||||
|
||||
bool operator >(const coordinates& o) const
|
||||
{
|
||||
if (m_line != o.m_line)
|
||||
return m_line > o.m_line;
|
||||
return m_column > o.m_column;
|
||||
}
|
||||
|
||||
bool operator <=(const coordinates& o) const
|
||||
{
|
||||
if (m_line != o.m_line)
|
||||
return m_line < o.m_line;
|
||||
return m_column <= o.m_column;
|
||||
}
|
||||
|
||||
bool operator >=(const coordinates& o) const
|
||||
{
|
||||
if (m_line != o.m_line)
|
||||
return m_line > o.m_line;
|
||||
return m_column >= o.m_column;
|
||||
}
|
||||
};
|
||||
|
||||
struct identifier
|
||||
{
|
||||
coordinates m_location;
|
||||
std::string m_declaration;
|
||||
};
|
||||
|
||||
typedef std::string string;
|
||||
typedef std::unordered_map<std::string, identifier> identifiers;
|
||||
typedef std::unordered_set<std::string> keywords;
|
||||
typedef std::map<int, std::string> error_markers;
|
||||
typedef std::unordered_set<int> breakpoints;
|
||||
typedef std::array<ImU32, (unsigned)pallete_index::max> palette;
|
||||
typedef uint8_t Char;
|
||||
|
||||
struct glyph
|
||||
{
|
||||
Char m_char;
|
||||
pallete_index m_color_idex = pallete_index::def;
|
||||
bool m_comment : 1;
|
||||
bool m_multiline_comment : 1;
|
||||
bool m_preprocessor : 1;
|
||||
|
||||
glyph(Char a_char, pallete_index a_color_index) : m_char(a_char), m_color_idex(a_color_index),
|
||||
m_comment(false), m_multiline_comment(false), m_preprocessor(false) {}
|
||||
};
|
||||
|
||||
typedef std::vector<glyph> line;
|
||||
typedef std::vector<line> lines;
|
||||
|
||||
struct language_definition
|
||||
{
|
||||
typedef std::pair<std::string, pallete_index> token_regex_string;
|
||||
typedef std::vector<token_regex_string> token_regex_strings;
|
||||
typedef bool(*tokenize_callback)(const char* in_begin, const char* in_end, const char*& out_begin, const char*& out_end, pallete_index& m_pallete_index);
|
||||
|
||||
std::string m_name;
|
||||
keywords m_keywords;
|
||||
identifiers m_identifiers;
|
||||
identifiers m_preproc_identifiers;
|
||||
std::string m_comment_start, m_comment_end, m_single_line_comment;
|
||||
char m_preproc_char;
|
||||
bool m_auto_indentation;
|
||||
|
||||
tokenize_callback m_tokenize;
|
||||
|
||||
token_regex_strings m_token_regex_strings;
|
||||
|
||||
bool m_case_sensitive;
|
||||
|
||||
language_definition()
|
||||
: m_preproc_char('#'), m_auto_indentation(true), m_tokenize(nullptr), m_case_sensitive(true)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
c_text_editor();
|
||||
~c_text_editor();
|
||||
|
||||
void set_error_markers(const error_markers& aMarkers) { m_error_markers = aMarkers; }
|
||||
void set_break_points(const breakpoints& aMarkers) { m_breakpoints = aMarkers; }
|
||||
|
||||
void render(const char* aTitle, const ImVec2& aSize = ImVec2(), bool aBorder = false);
|
||||
void set_text(const std::string& aText);
|
||||
std::string get_text() const;
|
||||
|
||||
void set_text_lines(const std::vector<std::string>& aLines);
|
||||
std::vector<std::string> get_text_lines() const;
|
||||
|
||||
std::string get_selected_text() const;
|
||||
std::string get_current_line_text()const;
|
||||
|
||||
int get_total_lines() const { return (int)m_lines.size(); }
|
||||
bool is_overwrite() const { return m_overwrite; }
|
||||
|
||||
void set_read_only(bool aValue);
|
||||
bool is_read_only() const { return m_read_only; }
|
||||
bool it_text_changed() const { return m_text_changed; }
|
||||
bool is_cursor_position_changed() const { return m_cursor_position_changed; }
|
||||
|
||||
bool is_colorizer_enabled() const { return m_colorizer_enabled; }
|
||||
void set_colorizer_enable(bool aValue);
|
||||
|
||||
coordinates get_cursor_position() const { return get_actual_cursor_coordinates(); }
|
||||
void set_cursor_position(const coordinates& aPosition);
|
||||
|
||||
inline void set_handle_mouse_inputs(bool aValue) { m_handle_mouse_inputs = aValue; }
|
||||
inline bool is_handle_mouse_inputs_enabled() const { return m_handle_keyboard_inputs; }
|
||||
|
||||
inline void set_handle_keyboard_inputs(bool aValue) { m_handle_keyboard_inputs = aValue; }
|
||||
inline bool is_handle_keyboard_inputs_enabled() const { return m_handle_keyboard_inputs; }
|
||||
|
||||
inline void set_imgui_child_ignored(bool aValue) { m_ignore_imgui_child = aValue; }
|
||||
inline bool is_imgui_child_ignored() const { return m_ignore_imgui_child; }
|
||||
|
||||
inline void set_show_whitespaces(bool aValue) { m_show_whitespaces = aValue; }
|
||||
inline bool is_showing_whitespaces() const { return m_show_whitespaces; }
|
||||
|
||||
void set_tab_size(int aValue);
|
||||
inline int get_tab_size() const { return m_tab_size; }
|
||||
|
||||
void insert_text(const std::string& aValue);
|
||||
void insert_text(const char* aValue);
|
||||
|
||||
void move_up(int aAmount = 1, bool aSelect = false);
|
||||
void move_down(int aAmount = 1, bool aSelect = false);
|
||||
void move_left(int aAmount = 1, bool aSelect = false, bool aWordMode = false);
|
||||
void move_right(int aAmount = 1, bool aSelect = false, bool aWordMode = false);
|
||||
void move_top(bool aSelect = false);
|
||||
void move_bottom(bool aSelect = false);
|
||||
void move_home(bool aSelect = false);
|
||||
void move_end(bool aSelect = false);
|
||||
|
||||
void set_selection_start(const coordinates& aPosition);
|
||||
void set_selection_end(const coordinates& aPosition);
|
||||
void set_selection(const coordinates& aStart, const coordinates& aEnd, selection_mode aMode = selection_mode::normal);
|
||||
void select_word_under_cursor();
|
||||
void select_all();
|
||||
bool has_selection() const;
|
||||
|
||||
void copy();
|
||||
void cut();
|
||||
void paste();
|
||||
void mdelete();
|
||||
|
||||
bool can_undo() const;
|
||||
bool can_redo() const;
|
||||
void undo(int aSteps = 1);
|
||||
void redo(int aSteps = 1);
|
||||
|
||||
private:
|
||||
typedef std::vector<std::pair<std::regex, pallete_index>> regex_list;
|
||||
|
||||
struct editor_state
|
||||
{
|
||||
coordinates m_selection_start;
|
||||
coordinates m_selection_end;
|
||||
coordinates m_cursor_position;
|
||||
};
|
||||
|
||||
class undo_record
|
||||
{
|
||||
public:
|
||||
undo_record() {}
|
||||
~undo_record() {}
|
||||
|
||||
undo_record(
|
||||
const std::string& aAdded,
|
||||
const c_text_editor::coordinates aAddedStart,
|
||||
const c_text_editor::coordinates aAddedEnd,
|
||||
|
||||
const std::string& aRemoved,
|
||||
const c_text_editor::coordinates aRemovedStart,
|
||||
const c_text_editor::coordinates aRemovedEnd,
|
||||
|
||||
c_text_editor::editor_state& aBefore,
|
||||
c_text_editor::editor_state& aAfter);
|
||||
|
||||
void undo(c_text_editor* aEditor);
|
||||
void redo(c_text_editor* aEditor);
|
||||
|
||||
std::string m_added;
|
||||
coordinates m_added_start;
|
||||
coordinates m_added_end;
|
||||
|
||||
std::string m_removed;
|
||||
coordinates m_removed_start;
|
||||
coordinates m_removed_end;
|
||||
|
||||
editor_state m_before;
|
||||
editor_state m_after;
|
||||
};
|
||||
|
||||
typedef std::vector<undo_record> undo_buffer;
|
||||
|
||||
void proces_inputs();
|
||||
void colorize(int aFromLine = 0, int aCount = -1);
|
||||
void colorize_range(int aFromLine = 0, int aToLine = 0);
|
||||
void colorize_internal();
|
||||
float text_distance_to_line_start(const coordinates& aFrom) const;
|
||||
void ensure_cursor_visible();
|
||||
int get_page_size() const;
|
||||
std::string get_text(const coordinates& aStart, const coordinates& aEnd) const;
|
||||
coordinates get_actual_cursor_coordinates() const;
|
||||
coordinates sanitize_coordinates(const coordinates& aValue) const;
|
||||
void advance(coordinates& aCoordinates) const;
|
||||
void delete_range(const coordinates& aStart, const coordinates& aEnd);
|
||||
int insert_text_at(coordinates& aWhere, const char* aValue);
|
||||
void add_undo(undo_record& aValue);
|
||||
coordinates screen_pos_to_coordinates(const ImVec2& aPosition) const;
|
||||
coordinates find_word_start(const coordinates& aFrom) const;
|
||||
coordinates find_word_end(const coordinates& aFrom) const;
|
||||
coordinates find_next_word(const coordinates& aFrom) const;
|
||||
int get_character_index(const coordinates& aCoordinates) const;
|
||||
int get_character_column(int a_line, int aIndex) const;
|
||||
int get_line_character_count(int a_line) const;
|
||||
int get_line_max_column(int a_line) const;
|
||||
bool is_on_word_boundary(const coordinates& aAt) const;
|
||||
void remove_line(int aStart, int aEnd);
|
||||
void remove_line(int aIndex);
|
||||
line& insert_line(int aIndex);
|
||||
void enter_character(ImWchar a_char, bool aShift);
|
||||
void backspace();
|
||||
void delete_selection();
|
||||
std::string get_word_under_cursor() const;
|
||||
std::string get_word_at(const coordinates& aCoords) const;
|
||||
ImU32 get_glyph_color(const glyph& aGlyph) const;
|
||||
|
||||
void handle_keyboard_inputs();
|
||||
void handle_mouse_inputs();
|
||||
void render();
|
||||
|
||||
float m_line_spacing;
|
||||
lines m_lines;
|
||||
editor_state m_state;
|
||||
undo_buffer m_undo_buffer;
|
||||
int m_undo_index;
|
||||
|
||||
int m_tab_size;
|
||||
bool m_overwrite;
|
||||
bool m_read_only;
|
||||
bool m_within_render;
|
||||
bool m_scroll_to_cursor;
|
||||
bool m_scroll_to_top;
|
||||
bool m_text_changed;
|
||||
bool m_colorizer_enabled;
|
||||
float m_text_start;
|
||||
int m_left_margin;
|
||||
bool m_cursor_position_changed;
|
||||
int m_color_range_min, m_color_range_max;
|
||||
selection_mode m_selection_mode;
|
||||
bool m_handle_keyboard_inputs;
|
||||
bool m_handle_mouse_inputs;
|
||||
bool m_ignore_imgui_child;
|
||||
bool m_show_whitespaces;
|
||||
|
||||
palette m_pallete_base;
|
||||
palette m_pallete;
|
||||
language_definition m_language_definition;
|
||||
regex_list m_regex_list;
|
||||
|
||||
bool m_check_comments;
|
||||
breakpoints m_breakpoints;
|
||||
error_markers m_error_markers;
|
||||
ImVec2 m_char_advance;
|
||||
coordinates m_interactive_start, m_interactive_end;
|
||||
std::string m_line_buffer;
|
||||
uint64_t m_start_time;
|
||||
|
||||
float m_last_click;
|
||||
};
|
||||
|
||||
inline c_text_editor* text_editor = new c_text_editor();
|
||||
@@ -0,0 +1,136 @@
|
||||
#include "imgui.h"
|
||||
|
||||
#include <D3DX11tex.h>
|
||||
#pragma comment(lib, "D3DX11.lib")
|
||||
|
||||
class c_settings
|
||||
{
|
||||
public:
|
||||
|
||||
struct
|
||||
{
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse;
|
||||
|
||||
std::string name = "S\nY\nN\nT\nH\nE\nT\nI\nC";
|
||||
|
||||
ImVec2 window_size = ImVec2(840, 630);
|
||||
ImVec2 padding = ImVec2(0, 0);
|
||||
ImVec2 item_spacing = ImVec2(4, 4);
|
||||
|
||||
float scrollbar_size = 20.f;
|
||||
float border_size = 0.f;
|
||||
|
||||
float general_rounding = 12.f;
|
||||
float rounding = 8.f;
|
||||
|
||||
bool slider_hovered = false;
|
||||
ImGuiID slider_id = 0;
|
||||
} c_window;
|
||||
|
||||
struct
|
||||
{
|
||||
ImVec2 child_window_padding = ImVec2(10, 10);
|
||||
ImVec2 child_item_spacing = ImVec2(10, 10);
|
||||
|
||||
float rounding = 4.f;
|
||||
|
||||
} c_child;
|
||||
|
||||
struct
|
||||
{
|
||||
float rounding = 2.f;
|
||||
|
||||
} c_element;
|
||||
|
||||
struct
|
||||
{
|
||||
float size = 11.f;
|
||||
float rounding = 2.f;
|
||||
ImVec2 padding = ImVec2(10, 10);
|
||||
ImVec2 picker_size = ImVec2(150, 100);
|
||||
ImVec2 bar_size = ImVec2(picker_size.x, 8);
|
||||
} c_picker;
|
||||
|
||||
struct
|
||||
{
|
||||
ID3D11ShaderResourceView* bg = nullptr;
|
||||
ID3D11ShaderResourceView* logo = nullptr;
|
||||
|
||||
} c_texture;
|
||||
|
||||
struct
|
||||
{
|
||||
ImFont* icon[7];
|
||||
ImFont* inter_medium[2];
|
||||
ImFont* name;
|
||||
|
||||
} c_font;
|
||||
|
||||
};
|
||||
|
||||
inline c_settings* set = new c_settings();
|
||||
|
||||
class c_colors
|
||||
{
|
||||
public:
|
||||
|
||||
struct
|
||||
{
|
||||
ImVec4 col_bg_alpha_0 = ImColor(125, 125, 125, 255);
|
||||
ImVec4 col_bg_alpha_1 = ImColor(185, 185, 185, 255);
|
||||
|
||||
ImVec4 accent_clr = ImColor(142, 132, 255, 255);
|
||||
|
||||
ImVec4 black_clr = ImColor(0, 0, 0, 255);
|
||||
ImVec4 white_clr = ImColor(255, 255, 255, 255);
|
||||
|
||||
} c_other_clr;
|
||||
|
||||
struct
|
||||
{
|
||||
ImVec4 general_layout = ImColor(0, 0, 0, 90);
|
||||
ImVec4 general_stroke = ImColor(21, 23, 26, 255);
|
||||
|
||||
ImVec4 layout = ImColor(13, 13, 18, 255);
|
||||
ImVec4 stroke = ImColor(19, 18, 26, 255);
|
||||
|
||||
} c_window;
|
||||
|
||||
struct
|
||||
{
|
||||
ImVec4 layout = ImColor(16, 16, 22, 255);
|
||||
ImVec4 stroke = ImColor(19, 18, 26, 255);
|
||||
|
||||
} c_child;
|
||||
|
||||
struct
|
||||
{
|
||||
ImVec4 dropdown_selection_layout = ImColor(31, 31, 41, 255);
|
||||
ImVec4 popup_icon = ImColor(45, 43, 62, 255);
|
||||
|
||||
ImVec4 checkbox_active = ImColor(37, 36, 53, 255);
|
||||
ImVec4 separator = ImColor(19, 18, 26, 255);
|
||||
|
||||
ImVec4 layout = ImColor(21, 21, 29, 255);
|
||||
ImVec4 circle = ImColor(41, 41, 53, 255);
|
||||
|
||||
} c_element;
|
||||
|
||||
struct
|
||||
{
|
||||
ImVec4 text_active = ImColor(255, 255, 255, 255);
|
||||
ImVec4 text_hov = ImColor(104, 104, 120, 255);
|
||||
ImVec4 text = ImColor(49, 49, 61, 255);
|
||||
|
||||
} c_text;
|
||||
|
||||
struct
|
||||
{
|
||||
ImVec4 background = ImColor(18, 18, 25);
|
||||
ImVec4 stroke = ImColor(23, 23, 31);
|
||||
} c_lua;
|
||||
|
||||
};
|
||||
|
||||
inline c_colors* clr = new c_colors();
|
||||
|
||||
@@ -0,0 +1,264 @@
|
||||
#include "imgui.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct lua_data;
|
||||
struct config_data;
|
||||
|
||||
class c_variable
|
||||
{
|
||||
public:
|
||||
|
||||
struct
|
||||
{
|
||||
ImGuiWindowFlags preview_flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoMove;
|
||||
|
||||
int box_c = 1;
|
||||
const char* box_type[2] = { "Default", "Corner" };
|
||||
|
||||
ImVec4 corner_color = ImColor(78, 78, 91);
|
||||
|
||||
bool flags = true;
|
||||
bool bars = true;
|
||||
bool esp_preview = true;
|
||||
|
||||
float texts_spacing = 15.f;
|
||||
float bars_spacing = 10.f;
|
||||
float box_padding = 10.f;
|
||||
|
||||
float anim_speed = 25.f;
|
||||
|
||||
} c_preview;
|
||||
|
||||
struct
|
||||
{
|
||||
|
||||
std::vector<std::string> selection_icon = { "K", "F", "H", "N", "V", "J", "E" };
|
||||
|
||||
int selection = 0, selection_active = 0;
|
||||
float selection_alpha = 1, selection_add;
|
||||
|
||||
} c_selection;
|
||||
|
||||
struct
|
||||
{
|
||||
std::vector<std::string> watermark_content = { "SYNTHETIC", "Server", "144FPS", "64PING", "12:15PM" };
|
||||
|
||||
bool watermark = true;
|
||||
int watermark_position = 1;
|
||||
|
||||
} c_watermark;
|
||||
|
||||
struct
|
||||
{
|
||||
int notify_position = 0;
|
||||
|
||||
} c_notify;
|
||||
|
||||
struct
|
||||
{
|
||||
float size = 11.f;
|
||||
float rounding = 2.f;
|
||||
ImVec2 padding = ImVec2(10, 10);
|
||||
ImVec2 picker_size = ImVec2(150, 150);
|
||||
ImVec2 bar_size = ImVec2(picker_size.x, 8);
|
||||
|
||||
} c_colorpicker;
|
||||
|
||||
struct
|
||||
{
|
||||
|
||||
float dpi = 1.f;
|
||||
int dpi_saved = 100;
|
||||
|
||||
bool dpi_changed = false;
|
||||
|
||||
} c_dpi;
|
||||
|
||||
struct
|
||||
{
|
||||
bool silent_aimbot = false;
|
||||
bool hit_chance = false;
|
||||
|
||||
bool ragebot = true;
|
||||
bool rage_holding = false;
|
||||
bool rage_value = false;
|
||||
bool rage_show_binds = false;
|
||||
int rage_key = 0;
|
||||
|
||||
int fov = 90;
|
||||
|
||||
} c_ragebot;
|
||||
|
||||
struct
|
||||
{
|
||||
int smoothness = 50;
|
||||
|
||||
bool enable_recoil = true;
|
||||
bool recoil_holding = false;
|
||||
bool recoil_value = false;
|
||||
bool recoil_show_binds = false;
|
||||
|
||||
int recoil_key = 0;
|
||||
|
||||
} c_recoil;
|
||||
|
||||
struct
|
||||
{
|
||||
int body_selection = 0;
|
||||
std::vector<std::string> body_list = { "Default", "Body" };
|
||||
|
||||
int points_selection = 0;
|
||||
std::vector<std::string> points_list = { "On limbs", "None" };
|
||||
|
||||
} c_other;
|
||||
|
||||
struct
|
||||
{
|
||||
bool head_safety = true;
|
||||
|
||||
int hit_chance = 10;
|
||||
int max_misses = 50;
|
||||
|
||||
bool point_scale = true;
|
||||
bool point_holding = false;
|
||||
bool point_value = false;
|
||||
bool point_show_binds = false;
|
||||
int point_key = 0;
|
||||
|
||||
} c_move;
|
||||
|
||||
struct
|
||||
{
|
||||
bool trigger_in_smoke = false;
|
||||
|
||||
bool enable_trigger = true;
|
||||
bool trigger_holding = false;
|
||||
bool trigger_value = false;
|
||||
bool trigger_show_binds = false;
|
||||
int trigger_key = 0;
|
||||
|
||||
} c_trigger;
|
||||
|
||||
struct
|
||||
{
|
||||
float pitch = 0.5f;
|
||||
float yaw = 0.5f;
|
||||
|
||||
bool head_safety = false;
|
||||
|
||||
bool point_scale = false;
|
||||
bool point_holding = false;
|
||||
bool point_value = false;
|
||||
bool point_show_binds = false;
|
||||
int point_key = 0;
|
||||
|
||||
} c_settings;
|
||||
|
||||
struct
|
||||
{
|
||||
bool esp = true;
|
||||
bool esp_holding = false;
|
||||
bool esp_value = false;
|
||||
bool esp_show_binds = false;
|
||||
int esp_key = 0;
|
||||
|
||||
bool through_walls = true;
|
||||
|
||||
int tracers_selection = 0;
|
||||
std::vector<std::string> tracers_list = { "Disabled", "In the field" };
|
||||
|
||||
bool dynamic_boxes = false;
|
||||
|
||||
bool ingame_radar = true;
|
||||
float inagame_color[4] = { 0.87f, 0.46f, 0.46f, 1.f };
|
||||
} c_esp;
|
||||
|
||||
struct
|
||||
{
|
||||
bool glow = true;
|
||||
bool glow_holding = false;
|
||||
bool glow_value = false;
|
||||
bool glow_show_binds = false;
|
||||
int glow_key = 0;
|
||||
|
||||
int power = 30;
|
||||
} c_glow;
|
||||
|
||||
struct
|
||||
{
|
||||
bool attachments = true;
|
||||
float attachments_color[4] = { 0.46f, 0.52f, 0.87f, 1.f };
|
||||
|
||||
bool teammates = true;
|
||||
bool teammates_holding = false;
|
||||
bool teammates_value = false;
|
||||
bool teammates_show_binds = false;
|
||||
int teammates_key = 0;
|
||||
|
||||
} c_attachments;
|
||||
|
||||
struct
|
||||
{
|
||||
bool chams = false;
|
||||
bool chams_holding = false;
|
||||
bool chams_value = false;
|
||||
bool chams_show_binds = false;
|
||||
int chams_key = 0;
|
||||
|
||||
bool backtrack = true;
|
||||
float backtrack_color[4] = { 0.46f, 0.52f, 0.87f, 1.f };
|
||||
|
||||
bool onshot = false;
|
||||
float onshot_color[4] = { 0.46f, 0.87f, 0.65f, 1.f };
|
||||
|
||||
bool ragdolls = true;
|
||||
float ragdolls_color[4] = { 0.87f, 0.65f, 0.46f, 1.f };
|
||||
|
||||
} c_chams;
|
||||
|
||||
struct
|
||||
{
|
||||
bool skeleton = true;
|
||||
|
||||
int snaplines_selection = 1;
|
||||
std::vector<std::string> snaplines_list = { "Top", "Bottom", "Left", "Right" };
|
||||
|
||||
bool weapon = true;
|
||||
float weapon_color[4] = { 1.f, 1.f, 1.f, 1.f };
|
||||
|
||||
bool nickname = true;
|
||||
float nickname_color[4] = { 1.f, 1.f, 1.f, 1.f };
|
||||
|
||||
} c_skeleton;
|
||||
|
||||
struct
|
||||
{
|
||||
std::vector<lua_data> data;
|
||||
|
||||
bool opened = false;
|
||||
bool create = false;
|
||||
|
||||
char name[128];
|
||||
std::string editable;
|
||||
|
||||
int sort_selection = 0;
|
||||
std::vector<std::string> sort_list = { "Newest", "Oldest" };
|
||||
} c_lua;
|
||||
|
||||
struct
|
||||
{
|
||||
std::vector<config_data> data;
|
||||
|
||||
bool create = false;
|
||||
int active = -1;
|
||||
|
||||
char name[128];
|
||||
|
||||
int sort_selection = 0;
|
||||
std::vector<std::string> sort_list = { "Newest", "Oldest" };
|
||||
|
||||
} c_config;
|
||||
};
|
||||
|
||||
inline c_variable* var = new c_variable();
|
||||
@@ -0,0 +1,96 @@
|
||||
#pragma once
|
||||
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
|
||||
#include "imgui.h"
|
||||
#include <d3d11.h>
|
||||
#include <d3dx11tex.h>
|
||||
#include "pshader.hpp"
|
||||
|
||||
inline ID3D11PixelShader* pshader = nullptr;
|
||||
inline ID3D11ShaderResourceView* tex = nullptr;
|
||||
inline ID3D11Device* device = nullptr;
|
||||
inline ID3D11DeviceContext* ctx = nullptr;
|
||||
|
||||
struct ImGui_ImplDX11_Data
|
||||
{
|
||||
ID3D11Device* pd3dDevice;
|
||||
ID3D11DeviceContext* pd3dDeviceContext;
|
||||
IDXGIFactory* pFactory;
|
||||
ID3D11Buffer* pVB;
|
||||
ID3D11Buffer* pIB;
|
||||
ID3D11VertexShader* pVertexShader;
|
||||
ID3D11InputLayout* pInputLayout;
|
||||
ID3D11Buffer* pVertexConstantBuffer;
|
||||
ID3D11PixelShader* pPixelShader;
|
||||
ID3D11SamplerState* pFontSampler;
|
||||
ID3D11ShaderResourceView* pFontTextureView;
|
||||
ID3D11RasterizerState* pRasterizerState;
|
||||
ID3D11BlendState* pBlendState;
|
||||
ID3D11DepthStencilState* pDepthStencilState;
|
||||
int VertexBufferSize;
|
||||
int IndexBufferSize;
|
||||
|
||||
ImGui_ImplDX11_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
||||
};
|
||||
|
||||
void safe_release(IUnknown*& resource) {
|
||||
if (resource != nullptr) {
|
||||
resource->Release();
|
||||
resource = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void get_back_buffer(IDXGISwapChain* swap_chain) {
|
||||
ID3D11Texture2D* back_buffer = nullptr;
|
||||
swap_chain->GetBuffer(0, IID_PPV_ARGS(&back_buffer));
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
back_buffer->GetDesc(&desc);
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
|
||||
ID3D11Texture2D* back_buffer_tex = NULL;
|
||||
device->CreateTexture2D(&desc, nullptr, &back_buffer_tex);
|
||||
ctx->CopyResource(back_buffer_tex, back_buffer);
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
|
||||
srvDesc.Format = desc.Format;
|
||||
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||
|
||||
safe_release(reinterpret_cast<IUnknown*&>(tex));
|
||||
device->CreateShaderResourceView(back_buffer_tex, &srvDesc, &tex);
|
||||
|
||||
safe_release(reinterpret_cast<IUnknown*&>(back_buffer));
|
||||
safe_release(reinterpret_cast<IUnknown*&>(back_buffer_tex));
|
||||
}
|
||||
|
||||
void begin(const ImDrawList* d, const ImDrawCmd* cmd) {
|
||||
const auto swap_chain = reinterpret_cast<IDXGISwapChain*>(cmd->UserCallbackData);
|
||||
auto bd = (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData;
|
||||
|
||||
if (!tex)
|
||||
get_back_buffer(swap_chain);
|
||||
|
||||
if (!pshader) {
|
||||
device->CreatePixelShader(pshaderd, sizeof(pshaderd), NULL, &pshader);
|
||||
}
|
||||
|
||||
ctx->PSSetShader(pshader, nullptr, 0);
|
||||
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||
}
|
||||
|
||||
void release(const ImDrawList* d, const ImDrawCmd* cmd) {
|
||||
safe_release(reinterpret_cast<IUnknown*&>(tex));
|
||||
}
|
||||
|
||||
void draw_background_blur(ImDrawList* draw_list, IDXGISwapChain* swap_chain, ID3D11Device* _device, ID3D11DeviceContext* _ctx, ImVec2 start, ImVec2 end, int rounding = 0, ImDrawFlags flags = 0) {
|
||||
|
||||
device = _device;
|
||||
ctx = _ctx;
|
||||
|
||||
draw_list->AddCallback(begin, swap_chain);
|
||||
draw_list->AddImageRounded(tex, start, end, start / ImGui::GetIO().DisplaySize, end / ImGui::GetIO().DisplaySize, ImColor{ 1.f, 1.f, 1.f, ImGui::GetStyle().Alpha }, rounding, flags);
|
||||
draw_list->AddCallback(ImDrawCallback_ResetRenderState, 0);
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
inline unsigned char pshaderd[] = {
|
||||
0x44, 0x58, 0x42, 0x43, 0xA5, 0xC3, 0xC0, 0x90, 0x87, 0xE3, 0xDA, 0x85, 0x3F, 0x95, 0xA5, 0x93,
|
||||
0xA6, 0xE4, 0x23, 0x06, 0x01, 0x00, 0x00, 0x00, 0xCC, 0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
0x34, 0x00, 0x00, 0x00, 0xF4, 0x00, 0x00, 0x00, 0x68, 0x01, 0x00, 0x00, 0x9C, 0x01, 0x00, 0x00,
|
||||
0x30, 0x04, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFF,
|
||||
0x00, 0x01, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x00, 0x52, 0x44, 0x31, 0x31, 0x3C, 0x00, 0x00, 0x00,
|
||||
0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
|
||||
0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x73, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x72, 0x30,
|
||||
0x00, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x30, 0x00, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73,
|
||||
0x6F, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4C, 0x53, 0x4C, 0x20, 0x53, 0x68, 0x61,
|
||||
0x64, 0x65, 0x72, 0x20, 0x43, 0x6F, 0x6D, 0x70, 0x69, 0x6C, 0x65, 0x72, 0x20, 0x31, 0x30, 0x2E,
|
||||
0x31, 0x00, 0xAB, 0xAB, 0x49, 0x53, 0x47, 0x4E, 0x6C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x0F, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x53, 0x56, 0x5F, 0x50,
|
||||
0x4F, 0x53, 0x49, 0x54, 0x49, 0x4F, 0x4E, 0x00, 0x43, 0x4F, 0x4C, 0x4F, 0x52, 0x00, 0x54, 0x45,
|
||||
0x58, 0x43, 0x4F, 0x4F, 0x52, 0x44, 0x00, 0xAB, 0x4F, 0x53, 0x47, 0x4E, 0x2C, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
|
||||
0x53, 0x56, 0x5F, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0xAB, 0xAB, 0x53, 0x48, 0x45, 0x58,
|
||||
0x8C, 0x02, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0xA3, 0x00, 0x00, 0x00, 0x6A, 0x08, 0x00, 0x01,
|
||||
0x5A, 0x00, 0x00, 0x03, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04,
|
||||
0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03,
|
||||
0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x89,
|
||||
0xC2, 0x00, 0x00, 0x80, 0x43, 0x55, 0x15, 0x00, 0x32, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x7E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0E, 0x00, 0x00, 0x0A, 0x32, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F,
|
||||
0x46, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xF2, 0x00, 0x10, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x42, 0x00, 0x10, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0xF4, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x00, 0x01,
|
||||
0x22, 0x00, 0x00, 0x07, 0x82, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00,
|
||||
0x0C, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x03,
|
||||
0x3A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x05, 0x82, 0x00, 0x10, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07,
|
||||
0x22, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xF2, 0x00, 0x10, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x46, 0x0E, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05,
|
||||
0x82, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0xF4, 0xFF, 0xFF, 0xFF,
|
||||
0x30, 0x00, 0x00, 0x01, 0x22, 0x00, 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x01, 0x40, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x04, 0x03, 0x2A, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x05,
|
||||
0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
|
||||
0x52, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x01, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x06, 0x11, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x8B, 0xC2, 0x00, 0x00, 0x80,
|
||||
0x43, 0x55, 0x15, 0x00, 0xF2, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x86, 0x00, 0x10, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x46, 0x7E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF2, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x46, 0x0E, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x0E, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x1E, 0x00, 0x00, 0x07, 0x82, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x10, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x01,
|
||||
0x36, 0x00, 0x00, 0x05, 0xF2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x0E, 0x10, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x2A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x16, 0x00, 0x00, 0x01, 0x38, 0x00, 0x00, 0x0A, 0xF2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x46, 0x0E, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x17, 0xB7, 0xD1, 0x3A,
|
||||
0x17, 0xB7, 0xD1, 0x3A, 0x17, 0xB7, 0xD1, 0x3A, 0x17, 0xB7, 0xD1, 0x3A, 0x3E, 0x00, 0x00, 0x01,
|
||||
0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
Reference in New Issue
Block a user