Compare commits

...

22 Commits
v1.09 ... v1.10

Author SHA1 Message Date
c07ab1b56a Minor tweaks to "Memory override" pull request 2014-08-31 12:02:22 +01:00
22a9555a99 Merge branch 'pr/40' 2014-08-31 11:54:45 +01:00
25080d53e5 Memory override #3 2014-08-31 14:58:21 +04:30
43448d9c89 Added FAQ/comments 2014-08-31 08:23:55 +01:00
e20077fbd0 Using spaces instead of tab for web readability 2014-08-30 20:06:53 +01:00
2c677c45c7 Added sample fonts data 2014-08-30 20:02:55 +01:00
3b339efeb2 Added IO.FontYOffset. Added asserts. 2014-08-30 20:02:10 +01:00
8fc50f5ed3 Remove IO.FontHeight, cached automatically. Added assertions. 2014-08-30 18:43:26 +01:00
dd5d251273 Added SetCursorPosX, SetCursorPosY shortcuts 2014-08-29 13:36:31 +01:00
2fb63b6068 Checkbox() return true when pressed 2014-08-28 17:32:03 +01:00
aa7fc37b37 removed malloc/free proxy fwd declares 2014-08-18 16:19:11 +04:30
c13c2449bb removed libimgui.pro 2014-08-18 16:09:47 +04:30
c2cb727ac9 memory override attempt #2 2014-08-18 16:08:03 +04:30
47fd8431c1 minor fixes 2014-08-18 13:19:35 +04:30
ef628a0a9d argh, removed redundent defines 2014-08-16 13:35:44 +04:30
df5a06f119 removed memory pools, they dont apply well 2014-08-16 13:34:45 +04:30
e9b697698a fixed a typo 2014-08-16 13:12:24 +04:30
5240013c90 merge with upstream 2014-08-16 13:00:39 +04:30
1956703c42 First attempt at memory management 2014-08-16 12:58:29 +04:30
6d6ee4e1f1 revert back to original 2014-08-14 19:21:01 +04:30
e9b0a61f48 :w
a
A
A
A
A
A
A
B
B
B
B
B
B
B
B
B
B
D
D
merged with upste
Merge remote-tracking branch 'upstream/master'
2014-08-14 18:59:08 +04:30
e3001fb986 project update 2014-08-11 20:43:24 +04:30
16 changed files with 227 additions and 60 deletions

BIN
extra_fonts/ProggyClean.zip Normal file

Binary file not shown.

BIN
extra_fonts/ProggySmall.zip Normal file

Binary file not shown.

71
extra_fonts/README.txt Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 949 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 949 B

View File

@ -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
View File

@ -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
View File

@ -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;