Compare commits
22 Commits
Author | SHA1 | Date | |
---|---|---|---|
c07ab1b56a | |||
22a9555a99 | |||
25080d53e5 | |||
43448d9c89 | |||
e20077fbd0 | |||
2c677c45c7 | |||
3b339efeb2 | |||
8fc50f5ed3 | |||
dd5d251273 | |||
2fb63b6068 | |||
aa7fc37b37 | |||
c13c2449bb | |||
c2cb727ac9 | |||
47fd8431c1 | |||
ef628a0a9d | |||
df5a06f119 | |||
e9b697698a | |||
5240013c90 | |||
1956703c42 | |||
6d6ee4e1f1 | |||
e9b0a61f48 | |||
e3001fb986 |
BIN
extra_fonts/ProggyClean.zip
Normal file
BIN
extra_fonts/ProggySmall.zip
Normal file
71
extra_fonts/README.txt
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
Extra fonts for ImGui.
|
||||
THOSE FONTS ARE OPTIONAL.
|
||||
|
||||
ImGui embeds a copy of 'proggy_clean' that you can use without any external files.
|
||||
Export your own font with bmfont (www.angelcode.com/products/bmfont).
|
||||
|
||||
bmfont reads fonts (.ttf, .fon, etc.) and output a .fnt file and a texture file, e.g:
|
||||
|
||||
proggy_clean.fon --> [bmfont] ---> proggy_clean_13.fnt
|
||||
proggy_clean_13.png
|
||||
|
||||
Configure bmfont:
|
||||
|
||||
- Export .fnt as Binary
|
||||
- Tip: uncheck "Render from TrueType outline" and "Font Smoothing" for best result with non-anti-aliased type fonts.
|
||||
But you can experiment with other settings if you want anti-aliased fonts.
|
||||
|
||||
|
||||
(A) Use font data embedded in ImGui
|
||||
|
||||
// Access embedded font data
|
||||
const void* fnt_data; // pointer to FNT data
|
||||
unsigned fnt_size; // size of FNT data
|
||||
const void* png_data; // pointer to PNG data
|
||||
unsigned int png_size; // size of PNG data
|
||||
ImGui::GetDefaultFontData(&fnt_data, &fnt_size, &png_data, &png_size);
|
||||
|
||||
1. Load the .FNT data from 'fnt_data' (NB: this is done for you by default if you don't do anything)
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Font = new ImBitmapFont();
|
||||
io.Font->LoadFromMemory(fnt_data, fnt_size);
|
||||
|
||||
2. Load the .PNG data from 'png_data' into a texture
|
||||
|
||||
|
||||
|
||||
(B) Use fonts from external files
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
1. Load the .FNT data, e.g.
|
||||
|
||||
// proggy_clean_13 [default]
|
||||
io.Font->LoadFromFile("proggy_clean_13.fnt");
|
||||
io.FontTexUvForWhite = ImVec2(0.0f/256.0f,0.0f/128);
|
||||
io.FontYOffset = +1;
|
||||
|
||||
// proggy_small_12
|
||||
io.Font = new ImBitmapFont();
|
||||
io.Font->LoadFromFile("proggy_small_12.fnt");
|
||||
io.FontTexUvForWhite = ImVec2(84.0f/256.0f,20.0f/64);
|
||||
io.FontYOffset = +2;
|
||||
|
||||
// proggy_small_14
|
||||
io.Font = new ImBitmapFont();
|
||||
io.Font->LoadFromFile("proggy_small_14.fnt");
|
||||
io.FontTexUvForWhite = ImVec2(84.0f/256.0f,20.0f/64);
|
||||
io.FontYOffset = +3;
|
||||
|
||||
// courier_new_16
|
||||
io.Font->LoadFromFile("courier_new_16.fnt");
|
||||
io.FontTexUvForWhite = ImVec2(1.0f/256.0f,4.0f/128);
|
||||
|
||||
// courier_new_18
|
||||
io.Font->LoadFromFile("courier_new_18.fnt");
|
||||
io.FontTexUvForWhite = ImVec2(4.0f/256.0f,5.0f/256);
|
||||
|
||||
2. Load the matching .PNG data into a texture
|
||||
|
BIN
extra_fonts/courier_new_16.fnt
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
extra_fonts/courier_new_16.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
extra_fonts/courier_new_18.fnt
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
extra_fonts/courier_new_18.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
extra_fonts/proggy_clean_13.fnt
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
extra_fonts/proggy_clean_13.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
extra_fonts/proggy_small_12.fnt
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
extra_fonts/proggy_small_12.png
Normal file
After Width: | Height: | Size: 949 B |
BIN
extra_fonts/proggy_small_14.fnt
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
extra_fonts/proggy_small_14.png
Normal file
After Width: | Height: | Size: 949 B |
@ -4,6 +4,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
//---- Define your own malloc/free/realloc functions if you want to override internal memory allocations for ImGui
|
||||
//#define IM_MALLOC(_SIZE) MyMalloc(_SIZE) // void* MyMalloc(size_t size);
|
||||
//#define IM_FREE(_PTR) MyFree(_PTR) // void MyFree(void *ptr);
|
||||
//#define IM_REALLOC(_PTR, _SIZE) MyRealloc(_PTR, _SIZE) // void* MyRealloc(void *ptr, size_t size);
|
||||
|
||||
//---- Define your own ImVector<> type if you don't want to use the provided implementation defined in imgui.h
|
||||
//#include <vector>
|
||||
//#define ImVector std::vector
|
||||
@ -35,3 +40,4 @@ namespace ImGui
|
||||
void Value(const char* prefix, const MyVec4& v, const char* float_format = NULL);
|
||||
};
|
||||
*/
|
||||
|
||||
|
181
imgui.cpp
@ -56,10 +56,11 @@
|
||||
3/ ImGui::Render() to render all the accumulated command-lists. it will call your RenderDrawListFn handler that you set in the IO structure.
|
||||
- all rendering information are stored into command-lists until ImGui::Render() is called.
|
||||
- effectively it means you can create widgets at any time in your code, regardless of "update" vs "render" considerations.
|
||||
- refer to the examples applications in the examples/ folder for instruction on how to setup your code.
|
||||
- a typical application skeleton may be:
|
||||
|
||||
// Application init
|
||||
// TODO: Fill all 'Settings' fields of the io structure
|
||||
// TODO: Fill all settings fields of the io structure
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.DisplaySize.x = 1920.0f;
|
||||
io.DisplaySize.y = 1280.0f;
|
||||
@ -87,14 +88,33 @@
|
||||
// swap video buffer, etc.
|
||||
}
|
||||
|
||||
TROUBLESHOOTING & FREQUENTLY ASKED QUESTIONS
|
||||
|
||||
- if text or lines are blurry when integrating ImGui in your engine:
|
||||
- in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
|
||||
- try adjusting ImGui::GetIO().PixelCenterOffset to 0.5f or 0.375f
|
||||
|
||||
- some widgets carry state and requires an unique ID to do so.
|
||||
- unique ID are typically derived from a string label, an indice or a pointer.
|
||||
- use PushID/PopID to easily create scopes and avoid ID conflicts. A Window is also an implicit scope.
|
||||
- when creating trees, ID are particularly important because you want to preserve the opened/closed state of tree nodes.
|
||||
- if you can only see text but no solid shapes or lines:
|
||||
- make sure io.FontTexUvForWhite is set to the texture coordinates of a pure white pixel in your texture.
|
||||
(this is done for you if you are using the default font)
|
||||
(ImGui is using this texture coordinate to draw solid objects so text and solid draw calls can be merged into one.)
|
||||
|
||||
- if you want to use a different font than the default:
|
||||
- create bitmap font data using BMFont, make sure that BMFont is exporting the .fnt file in Binary mode.
|
||||
io.Font = new ImBitmapFont();
|
||||
io.Font->LoadFromFile("path_to_your_fnt_file.fnt");
|
||||
- load your texture yourself. texture *MUST* have white pixel at UV coordinate io.FontTexUvForWhite. This is used to draw all solid shapes.
|
||||
- the extra_fonts/ folder provides examples of using external fonts.
|
||||
|
||||
- if you are confused about the meaning or use of ID in ImGui:
|
||||
- some widgets requires state to be carried over multiple frames (most typically ImGui often wants remember what is the "active" widget).
|
||||
to do so they need an unique ID. unique ID are typically derived from a string label, an indice or a pointer.
|
||||
when you call Button("OK") the button shows "OK" and also use "OK" as an ID.
|
||||
- ID are uniquely scoped within Windows so no conflict can happen if you have two buttons called "OK" in two different Windows.
|
||||
within a same Window, use PushID() / PopID() to easily create scopes and avoid ID conflicts.
|
||||
so if you have a loop creating "multiple" items, you can use PushID() / PopID() with the index of each item, or their pointer, etc.
|
||||
some functions like TreeNode() implicitly creates a scope for you by calling PushID()
|
||||
- when dealing with trees, ID are important because you want to preserve the opened/closed state of tree nodes.
|
||||
depending on your use cases you may want to use strings, indices or pointers as ID. experiment and see what makes more sense!
|
||||
e.g. When displaying a single object, using a static string as ID will preserve your node open/closed state when the targetted object change
|
||||
e.g. When displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state per object
|
||||
@ -102,14 +122,12 @@
|
||||
e.g. "Label" display "Label" and uses "Label" as ID
|
||||
e.g. "Label##Foobar" display "Label" and uses "Label##Foobar" as ID
|
||||
e.g. "##Foobar" display an empty label and uses "##Foobar" as ID
|
||||
|
||||
- if you want to use a different font than the default
|
||||
- create bitmap font data using BMFont. allocate ImGui::GetIO().Font and use ->LoadFromFile()/LoadFromMemory(), set ImGui::GetIO().FontHeight
|
||||
- load your texture yourself. texture *MUST* have white pixel at UV coordinate Imgui::GetIO().FontTexUvForWhite. This is used to draw all solid shapes.
|
||||
- read articles about the imgui principles (see web links) to understand the requirement and use of ID.
|
||||
|
||||
- tip: the construct 'if (IMGUI_ONCE_UPON_A_FRAME)' will evaluate to true only once a frame, you can use it to add custom UI in the middle of a deep nested inner loop in your code.
|
||||
- tip: you can call Render() multiple times (e.g for VR renders), up to you to communicate the extra state to your RenderDrawListFn function.
|
||||
- tip: you can create widgets without a Begin/End block, they will go in an implicit window called "Debug"
|
||||
- tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug"
|
||||
- tip: read the ShowTestWindow() code for more example of how to use ImGui!
|
||||
|
||||
ISSUES AND TODO-LIST
|
||||
|
||||
@ -170,6 +188,7 @@
|
||||
#include <stdint.h> // intptr_t
|
||||
#include <stdio.h> // vsnprintf
|
||||
#include <string.h> // memset
|
||||
#include <new> // new (ptr)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
|
||||
@ -279,6 +298,7 @@ ImGuiIO::ImGuiIO()
|
||||
IniFilename = "imgui.ini";
|
||||
LogFilename = "imgui_log.txt";
|
||||
Font = NULL;
|
||||
FontYOffset = 0.0f;
|
||||
FontTexUvForWhite = ImVec2(0.0f,0.0f);
|
||||
FontAllowScaling = false;
|
||||
PixelCenterOffset = 0.0f;
|
||||
@ -354,6 +374,14 @@ static int ImStricmp(const char* str1, const char* str2)
|
||||
return d;
|
||||
}
|
||||
|
||||
static char* ImStrdup(const char *str)
|
||||
{
|
||||
char *buff = (char*)IM_MALLOC(strlen(str) + 1);
|
||||
IM_ASSERT(buff);
|
||||
strcpy(buff, str);
|
||||
return buff;
|
||||
}
|
||||
|
||||
static const char* ImStristr(const char* haystack, const char* needle, const char* needle_end)
|
||||
{
|
||||
if (!needle_end)
|
||||
@ -596,7 +624,7 @@ struct ImGuiIniData
|
||||
bool Collapsed;
|
||||
|
||||
ImGuiIniData() { memset(this, 0, sizeof(*this)); }
|
||||
~ImGuiIniData() { if (Name) { free(Name); Name = NULL; } }
|
||||
~ImGuiIniData() { if (Name) { IM_FREE(Name); Name = NULL; } }
|
||||
};
|
||||
|
||||
struct ImGuiState
|
||||
@ -604,6 +632,8 @@ struct ImGuiState
|
||||
bool Initialized;
|
||||
ImGuiIO IO;
|
||||
ImGuiStyle Style;
|
||||
float FontSize; // == IO.Font->GetFontSize(). Vertical distance between two lines of text, aka == CalcTextSize(" ").y
|
||||
|
||||
float Time;
|
||||
int FrameCount;
|
||||
int FrameCountRendered;
|
||||
@ -635,7 +665,7 @@ struct ImGuiState
|
||||
// Logging
|
||||
bool LogEnabled;
|
||||
FILE* LogFile;
|
||||
ImGuiTextBuffer LogClipboard;
|
||||
ImGuiTextBuffer* LogClipboard; // pointer so our GImGui static constructor doesn't call heap allocators.
|
||||
int LogAutoExpandMaxDepth;
|
||||
|
||||
ImGuiState()
|
||||
@ -658,6 +688,7 @@ struct ImGuiState
|
||||
LogEnabled = false;
|
||||
LogFile = NULL;
|
||||
LogAutoExpandMaxDepth = 2;
|
||||
LogClipboard = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
@ -709,7 +740,7 @@ public:
|
||||
|
||||
ImGuiAabb Aabb() const { return ImGuiAabb(Pos, Pos+Size); }
|
||||
ImFont Font() const { return GImGui.IO.Font; }
|
||||
float FontSize() const { return GImGui.IO.FontHeight * FontScale; }
|
||||
float FontSize() const { return GImGui.FontSize * FontScale; }
|
||||
ImVec2 CursorPos() const { return DC.CursorPos; }
|
||||
float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0 : FontSize() + GImGui.Style.FramePadding.y * 2.0f; }
|
||||
ImGuiAabb TitleBarAabb() const { return ImGuiAabb(Pos, Pos + ImVec2(SizeFull.x, TitleBarHeight())); }
|
||||
@ -923,7 +954,7 @@ void ImGuiTextBuffer::append(const char* fmt, ...)
|
||||
|
||||
ImGuiWindow::ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_size)
|
||||
{
|
||||
Name = strdup(name);
|
||||
Name = ImStrdup(name);
|
||||
ID = GetID(name);
|
||||
IDStack.push_back(ID);
|
||||
|
||||
@ -950,14 +981,16 @@ ImGuiWindow::ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_si
|
||||
FocusIdxRequestCurrent = IM_INT_MAX;
|
||||
FocusIdxRequestNext = IM_INT_MAX;
|
||||
|
||||
DrawList = new ImDrawList();
|
||||
DrawList = (ImDrawList*)IM_MALLOC(sizeof(ImDrawList));
|
||||
new(DrawList) ImDrawList();
|
||||
}
|
||||
|
||||
ImGuiWindow::~ImGuiWindow()
|
||||
{
|
||||
delete DrawList;
|
||||
DrawList->~ImDrawList();
|
||||
IM_FREE(DrawList);
|
||||
DrawList = NULL;
|
||||
free(Name);
|
||||
IM_FREE(Name);
|
||||
Name = NULL;
|
||||
}
|
||||
|
||||
@ -1037,8 +1070,9 @@ static ImGuiIniData* FindWindowSettings(const char* name)
|
||||
if (ImStricmp(ini->Name, name) == 0)
|
||||
return ini;
|
||||
}
|
||||
ImGuiIniData* ini = new ImGuiIniData();
|
||||
ini->Name = strdup(name);
|
||||
ImGuiIniData* ini = (ImGuiIniData*)IM_MALLOC(sizeof(ImGuiIniData));
|
||||
new(ini) ImGuiIniData();
|
||||
ini->Name = ImStrdup(name);
|
||||
ini->Collapsed = false;
|
||||
ini->Pos = ImVec2(FLT_MAX,FLT_MAX);
|
||||
ini->Size = ImVec2(0,0);
|
||||
@ -1076,12 +1110,12 @@ static void LoadSettings()
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
char* f_data = new char[f_size+1];
|
||||
char* f_data = (char*)IM_MALLOC(f_size+1);
|
||||
f_size = fread(f_data, 1, f_size, f); // Text conversion alter read size so let's not be fussy about return value
|
||||
fclose(f);
|
||||
if (f_size == 0)
|
||||
{
|
||||
delete[] f_data;
|
||||
IM_FREE(f_data);
|
||||
return;
|
||||
}
|
||||
f_data[f_size] = 0;
|
||||
@ -1115,7 +1149,7 @@ static void LoadSettings()
|
||||
line_start = line_end+1;
|
||||
}
|
||||
|
||||
delete[] f_data;
|
||||
IM_FREE(f_data);
|
||||
}
|
||||
|
||||
static void SaveSettings()
|
||||
@ -1187,6 +1221,9 @@ void NewFrame()
|
||||
if (!g.Initialized)
|
||||
{
|
||||
// Initialize on first frame
|
||||
g.LogClipboard = (ImGuiTextBuffer*)IM_MALLOC(sizeof(ImGuiTextBuffer));
|
||||
new(g.LogClipboard) ImGuiTextBuffer();
|
||||
|
||||
IM_ASSERT(g.Settings.empty());
|
||||
LoadSettings();
|
||||
if (!g.IO.Font)
|
||||
@ -1195,16 +1232,19 @@ void NewFrame()
|
||||
const void* fnt_data;
|
||||
unsigned int fnt_size;
|
||||
ImGui::GetDefaultFontData(&fnt_data, &fnt_size, NULL, NULL);
|
||||
g.IO.Font = new ImBitmapFont();
|
||||
g.IO.Font = (ImBitmapFont*)IM_MALLOC(sizeof(ImBitmapFont));
|
||||
new(g.IO.Font) ImBitmapFont();
|
||||
g.IO.Font->LoadFromMemory(fnt_data, fnt_size);
|
||||
g.IO.FontHeight = g.IO.Font->GetFontSize();
|
||||
g.IO.FontYOffset = +1;
|
||||
}
|
||||
g.Initialized = true;
|
||||
}
|
||||
IM_ASSERT(g.IO.Font && g.IO.Font->IsLoaded()); // Font not loaded
|
||||
|
||||
g.Time += g.IO.DeltaTime;
|
||||
g.FrameCount += 1;
|
||||
g.Tooltip[0] = '\0';
|
||||
g.FontSize = g.IO.Font->GetFontSize();
|
||||
|
||||
// Update inputs state
|
||||
if (g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0)
|
||||
@ -1320,14 +1360,21 @@ void Shutdown()
|
||||
SaveSettings();
|
||||
|
||||
for (size_t i = 0; i < g.Windows.size(); i++)
|
||||
delete g.Windows[i];
|
||||
{
|
||||
g.Windows[i]->~ImGuiWindow();
|
||||
IM_FREE(g.Windows[i]);
|
||||
}
|
||||
g.Windows.clear();
|
||||
g.CurrentWindowStack.clear();
|
||||
g.RenderDrawLists.clear();
|
||||
g.FocusedWindow = NULL;
|
||||
g.HoveredWindow = NULL;
|
||||
g.HoveredWindowExcludingChilds = NULL;
|
||||
for (size_t i = 0; i < g.Settings.size(); i++)
|
||||
delete g.Settings[i];
|
||||
{
|
||||
g.Settings[i]->~ImGuiIniData();
|
||||
IM_FREE(g.Settings[i]);
|
||||
}
|
||||
g.Settings.clear();
|
||||
g.ColorEditModeStorage.Clear();
|
||||
if (g.LogFile && g.LogFile != stdout)
|
||||
@ -1337,16 +1384,23 @@ void Shutdown()
|
||||
}
|
||||
if (g.IO.Font)
|
||||
{
|
||||
delete g.IO.Font;
|
||||
g.IO.Font->~ImBitmapFont();
|
||||
IM_FREE(g.IO.Font);
|
||||
g.IO.Font = NULL;
|
||||
}
|
||||
|
||||
if (g.PrivateClipboard)
|
||||
{
|
||||
free(g.PrivateClipboard);
|
||||
IM_FREE(g.PrivateClipboard);
|
||||
g.PrivateClipboard = NULL;
|
||||
}
|
||||
|
||||
if (g.LogClipboard)
|
||||
{
|
||||
g.LogClipboard->~ImGuiTextBuffer();
|
||||
IM_FREE(g.LogClipboard);
|
||||
}
|
||||
|
||||
g.Initialized = false;
|
||||
}
|
||||
|
||||
@ -1511,9 +1565,9 @@ static void LogText(const ImVec2& ref_pos, const char* text, const char* text_en
|
||||
else
|
||||
{
|
||||
if (log_new_line || !is_first_line)
|
||||
g.LogClipboard.append("\n%*s%.*s", tree_depth*4, "", char_count, text_remaining);
|
||||
g.LogClipboard->append("\n%*s%.*s", tree_depth*4, "", char_count, text_remaining);
|
||||
else
|
||||
g.LogClipboard.append(" %.*s", char_count, text_remaining);
|
||||
g.LogClipboard->append(" %.*s", char_count, text_remaining);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1836,7 +1890,8 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin
|
||||
// Create window the first time, and load settings
|
||||
if (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip))
|
||||
{
|
||||
window = new ImGuiWindow(name, ImVec2(0,0), size);
|
||||
window = (ImGuiWindow*)IM_MALLOC(sizeof(ImGuiWindow));
|
||||
new(window) ImGuiWindow(name, ImVec2(0,0), size);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1844,7 +1899,8 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin
|
||||
if (settings && ImLength(settings->Size) > 0.0f && !(flags & ImGuiWindowFlags_NoResize))// && ImLengthsize) == 0.0f)
|
||||
size = settings->Size;
|
||||
|
||||
window = new ImGuiWindow(name, g.NewWindowDefaultPos, size);
|
||||
window = (ImGuiWindow*)IM_MALLOC(sizeof(ImGuiWindow));
|
||||
new(window) ImGuiWindow(name, g.NewWindowDefaultPos, size);
|
||||
|
||||
if (settings->Pos.x != FLT_MAX)
|
||||
{
|
||||
@ -2244,12 +2300,12 @@ void End()
|
||||
fclose(g.LogFile);
|
||||
g.LogFile = NULL;
|
||||
}
|
||||
if (g.LogClipboard.size() > 1)
|
||||
if (g.LogClipboard->size() > 1)
|
||||
{
|
||||
g.LogClipboard.append("\n");
|
||||
g.LogClipboard->append("\n");
|
||||
if (g.IO.SetClipboardTextFn)
|
||||
g.IO.SetClipboardTextFn(g.LogClipboard.begin(), g.LogClipboard.end());
|
||||
g.LogClipboard.clear();
|
||||
g.IO.SetClipboardTextFn(g.LogClipboard->begin(), g.LogClipboard->end());
|
||||
g.LogClipboard->clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2461,6 +2517,18 @@ void SetCursorPos(const ImVec2& pos)
|
||||
window->DC.CursorPos = window->Pos + pos;
|
||||
}
|
||||
|
||||
void SetCursorPosX(float x)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
window->DC.CursorPos.x = window->Pos.x + x;
|
||||
}
|
||||
|
||||
void SetCursorPosY(float y)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
window->DC.CursorPos.y = window->Pos.y + y;
|
||||
}
|
||||
|
||||
ImVec2 GetCursorScreenPos()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
@ -3495,12 +3563,12 @@ void PlotHistogram(const char* label, const float* values, int values_count, int
|
||||
ImGui::Plot(ImGuiPlotType_Histogram, label, values, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size, stride);
|
||||
}
|
||||
|
||||
void Checkbox(const char* label, bool* v)
|
||||
bool Checkbox(const char* label, bool* v)
|
||||
{
|
||||
ImGuiState& g = GImGui;
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return;
|
||||
return false;
|
||||
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
@ -3516,7 +3584,7 @@ void Checkbox(const char* label, bool* v)
|
||||
const ImGuiAabb total_bb(ImMin(check_bb.Min, text_bb.Min), ImMax(check_bb.Max, text_bb.Max));
|
||||
|
||||
if (ClipAdvance(total_bb))
|
||||
return;
|
||||
return false;
|
||||
|
||||
const bool hovered = (g.HoveredWindow == window) && (g.HoveredId == 0) && IsMouseHoveringBox(total_bb);
|
||||
const bool pressed = hovered && g.IO.MouseClicked[0];
|
||||
@ -3537,16 +3605,19 @@ void Checkbox(const char* label, bool* v)
|
||||
if (g.LogEnabled)
|
||||
LogText(text_bb.GetTL(), *v ? "[x]" : "[ ]");
|
||||
RenderText(text_bb.GetTL(), label);
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
void CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value)
|
||||
bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value)
|
||||
{
|
||||
bool v = (*flags & flags_value) ? true : false;
|
||||
ImGui::Checkbox(label, &v);
|
||||
bool pressed = ImGui::Checkbox(label, &v);
|
||||
if (v)
|
||||
*flags |= flags_value;
|
||||
else
|
||||
*flags &= ~flags_value;
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool RadioButton(const char* label, bool active)
|
||||
@ -3932,7 +4003,7 @@ bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlag
|
||||
{
|
||||
// Remove new-line from pasted buffer
|
||||
size_t clipboard_len = strlen(clipboard);
|
||||
char* clipboard_filtered = (char*)malloc(clipboard_len+1);
|
||||
char* clipboard_filtered = (char*)IM_MALLOC(clipboard_len+1);
|
||||
int clipboard_filtered_len = 0;
|
||||
for (int i = 0; clipboard[i]; i++)
|
||||
{
|
||||
@ -3943,7 +4014,7 @@ bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlag
|
||||
}
|
||||
clipboard_filtered[clipboard_filtered_len] = 0;
|
||||
stb_textedit_paste(&edit_state, &edit_state.StbState, clipboard_filtered, clipboard_filtered_len);
|
||||
free(clipboard_filtered);
|
||||
IM_FREE(clipboard_filtered);
|
||||
}
|
||||
}
|
||||
else if (g.IO.InputCharacters[0])
|
||||
@ -5062,7 +5133,7 @@ ImBitmapFont::ImBitmapFont()
|
||||
void ImBitmapFont::Clear()
|
||||
{
|
||||
if (Data && DataOwned)
|
||||
free(Data);
|
||||
IM_FREE(Data);
|
||||
Data = NULL;
|
||||
DataOwned = false;
|
||||
Info = NULL;
|
||||
@ -5075,6 +5146,8 @@ void ImBitmapFont::Clear()
|
||||
|
||||
bool ImBitmapFont::LoadFromFile(const char* filename)
|
||||
{
|
||||
IM_ASSERT(!IsLoaded()); // Call Clear()
|
||||
|
||||
// Load file
|
||||
FILE* f;
|
||||
if ((f = fopen(filename, "rb")) == NULL)
|
||||
@ -5087,7 +5160,7 @@ bool ImBitmapFont::LoadFromFile(const char* filename)
|
||||
DataSize = (size_t)f_size;
|
||||
if (fseek(f, 0, SEEK_SET))
|
||||
return false;
|
||||
if ((Data = (unsigned char*)malloc(DataSize)) == NULL)
|
||||
if ((Data = (unsigned char*)IM_MALLOC(DataSize)) == NULL)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
@ -5095,7 +5168,7 @@ bool ImBitmapFont::LoadFromFile(const char* filename)
|
||||
if (fread(Data, 1, DataSize, f) != DataSize)
|
||||
{
|
||||
fclose(f);
|
||||
free(Data);
|
||||
IM_FREE(Data);
|
||||
return false;
|
||||
}
|
||||
fclose(f);
|
||||
@ -5105,7 +5178,9 @@ bool ImBitmapFont::LoadFromFile(const char* filename)
|
||||
|
||||
bool ImBitmapFont::LoadFromMemory(const void* data, size_t data_size)
|
||||
{
|
||||
Data = (unsigned char*)data;
|
||||
IM_ASSERT(!IsLoaded()); // Call Clear()
|
||||
|
||||
Data = (unsigned char*)data;
|
||||
DataSize = data_size;
|
||||
|
||||
// Parse data
|
||||
@ -5244,7 +5319,7 @@ void ImBitmapFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& c
|
||||
|
||||
// Align to be pixel perfect
|
||||
pos.x = (float)(int)pos.x;
|
||||
pos.y = (float)(int)pos.y;
|
||||
pos.y = (float)(int)pos.y + GImGui.IO.FontYOffset;
|
||||
|
||||
const ImVec4 clip_rect = clip_rect_ref;
|
||||
|
||||
@ -5336,7 +5411,7 @@ static const char* GetClipboardTextFn_DefaultImpl()
|
||||
static char* buf_local = NULL;
|
||||
if (buf_local)
|
||||
{
|
||||
free(buf_local);
|
||||
IM_FREE(buf_local);
|
||||
buf_local = NULL;
|
||||
}
|
||||
if (!OpenClipboard(NULL))
|
||||
@ -5345,7 +5420,7 @@ static const char* GetClipboardTextFn_DefaultImpl()
|
||||
if (buf_handle == NULL)
|
||||
return NULL;
|
||||
if (char* buf_global = (char*)GlobalLock(buf_handle))
|
||||
buf_local = strdup(buf_global);
|
||||
buf_local = ImStrdup(buf_global);
|
||||
GlobalUnlock(buf_handle);
|
||||
CloseClipboard();
|
||||
return buf_local;
|
||||
@ -5384,12 +5459,12 @@ static void SetClipboardTextFn_DefaultImpl(const char* text, const char* text_en
|
||||
{
|
||||
if (GImGui.PrivateClipboard)
|
||||
{
|
||||
free(GImGui.PrivateClipboard);
|
||||
IM_FREE(GImGui.PrivateClipboard);
|
||||
GImGui.PrivateClipboard = NULL;
|
||||
}
|
||||
if (!text_end)
|
||||
text_end = text + strlen(text);
|
||||
GImGui.PrivateClipboard = (char*)malloc((size_t)(text_end - text) + 1);
|
||||
GImGui.PrivateClipboard = (char*)IM_MALLOC((size_t)(text_end - text) + 1);
|
||||
memcpy(GImGui.PrivateClipboard, text, (size_t)(text_end - text));
|
||||
GImGui.PrivateClipboard[(size_t)(text_end - text)] = 0;
|
||||
}
|
||||
@ -5923,7 +5998,7 @@ void ShowTestWindow(bool* open)
|
||||
/*
|
||||
// Copyright (c) 2004, 2005 Tristan Grimmer
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
|
29
imgui.h
@ -17,7 +17,19 @@ struct ImGuiWindow;
|
||||
#include "imconfig.h"
|
||||
#include <float.h> // FLT_MAX
|
||||
#include <stdarg.h> // va_list
|
||||
#include <stdlib.h> // NULL
|
||||
#include <stdlib.h> // NULL, malloc
|
||||
|
||||
#ifndef IM_MALLOC
|
||||
#define IM_MALLOC(_SIZE) malloc((_SIZE))
|
||||
#endif
|
||||
|
||||
#ifndef IM_FREE
|
||||
#define IM_FREE(_PTR) free((_PTR))
|
||||
#endif
|
||||
|
||||
#ifndef IM_REALLOC
|
||||
#define IM_REALLOC(_PTR, _SIZE) realloc((_PTR), (_SIZE))
|
||||
#endif
|
||||
|
||||
#ifndef IM_ASSERT
|
||||
#include <assert.h>
|
||||
@ -72,7 +84,7 @@ public:
|
||||
typedef const value_type* const_iterator;
|
||||
|
||||
ImVector() { Size = Capacity = 0; Data = NULL; }
|
||||
~ImVector() { if (Data) free(Data); }
|
||||
~ImVector() { if (Data) IM_FREE(Data); }
|
||||
|
||||
inline bool empty() const { return Size == 0; }
|
||||
inline size_t size() const { return Size; }
|
||||
@ -83,7 +95,7 @@ public:
|
||||
inline value_type& operator[](size_t i) { IM_ASSERT(i < Size); return Data[i]; }
|
||||
inline const value_type& operator[](size_t i) const { IM_ASSERT(i < Size); return Data[i]; }
|
||||
|
||||
inline void clear() { if (Data) { Size = Capacity = 0; free(Data); Data = NULL; } }
|
||||
inline void clear() { if (Data) { Size = Capacity = 0; IM_FREE(Data); Data = NULL; } }
|
||||
inline iterator begin() { return Data; }
|
||||
inline const_iterator begin() const { return Data; }
|
||||
inline iterator end() { return Data + Size; }
|
||||
@ -94,7 +106,7 @@ public:
|
||||
inline const value_type& back() const { IM_ASSERT(Size > 0); return at(Size-1); }
|
||||
inline void swap(ImVector<T>& rhs) { const size_t rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; const size_t rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; }
|
||||
|
||||
inline void reserve(size_t new_capacity) { Data = (value_type*)realloc(Data, new_capacity * sizeof(value_type)); Capacity = new_capacity; }
|
||||
inline void reserve(size_t new_capacity) { Data = (value_type*)IM_REALLOC(Data, new_capacity * sizeof(value_type)); Capacity = new_capacity; }
|
||||
inline void resize(size_t new_size) { if (new_size > Capacity) reserve(new_size); Size = new_size; }
|
||||
|
||||
inline void push_back(const value_type& v) { if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); Data[Size++] = v; }
|
||||
@ -168,6 +180,8 @@ namespace ImGui
|
||||
float GetColumnWidth(int column_index = -1);
|
||||
ImVec2 GetCursorPos(); // cursor position relative to window position
|
||||
void SetCursorPos(const ImVec2& pos); // "
|
||||
void SetCursorPosX(float x); // "
|
||||
void SetCursorPosY(float y); // "
|
||||
ImVec2 GetCursorScreenPos(); // cursor position in screen space
|
||||
void AlignFirstTextHeightToWidgets(); // call once if the first item on the line is a Text() item and you want to vertically lower it to match higher widgets.
|
||||
float GetTextLineSpacing();
|
||||
@ -197,8 +211,8 @@ namespace ImGui
|
||||
bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f");
|
||||
void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float));
|
||||
void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float));
|
||||
void Checkbox(const char* label, bool* v);
|
||||
void CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
|
||||
bool Checkbox(const char* label, bool* v);
|
||||
bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
|
||||
bool RadioButton(const char* label, bool active);
|
||||
bool RadioButton(const char* label, int* v, int v_button);
|
||||
bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1);
|
||||
@ -389,7 +403,7 @@ struct ImGuiIO
|
||||
float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels.
|
||||
int KeyMap[ImGuiKey_COUNT]; // <unset> // Map of indices into the KeysDown[512] entries array
|
||||
ImFont Font; // <auto> // Gets passed to text functions. Typedef ImFont to the type you want (ImBitmapFont* or your own font).
|
||||
float FontHeight; // <auto> // Default font height, must be the vertical distance between two lines of text, aka == CalcTextSize(" ").y
|
||||
float FontYOffset; // = 0.0f // Offset font rendering by xx pixels in Y axis.
|
||||
ImVec2 FontTexUvForWhite; // = (0.0f,0.0f) // Font texture must have a white pixel at this UV coordinate. Adjust if you are using custom texture.
|
||||
bool FontAllowScaling; // = false // Set to allow scaling text with CTRL+Wheel.
|
||||
float PixelCenterOffset; // = 0.0f // Try to set to 0.5f or 0.375f if rendering is blurry
|
||||
@ -640,6 +654,7 @@ struct ImBitmapFont
|
||||
void BuildLookupTable();
|
||||
const FntGlyph * FindGlyph(unsigned short c) const;
|
||||
float GetFontSize() const { return (float)Info->FontSize; }
|
||||
bool IsLoaded() const { return Info != NULL && Common != NULL && Glyphs != NULL; }
|
||||
|
||||
ImVec2 CalcTextSize(float size, float max_width, const char* text_begin, const char* text_end, const char** remaining = NULL) const;
|
||||
void RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawVert*& out_vertices) const;
|
||||
|