Compare commits

...

18 Commits
v1.07 ... v1.08

Author SHA1 Message Date
d17a586738 Fixed ImGuiTextFilter triming of leading/trailing blanks. Documented "Filtering" section of demo better. 2014-08-25 17:19:04 +01:00
710b9b68b1 Merge pull request #29 from Roflraging/master
Disable client state in OpenGL example after rendering.
2014-08-25 16:58:54 +01:00
29ba288ea0 Merge pull request #31 from orbitcowboy/master
Fixed file descriptor leak on LoadSettings() failure
2014-08-25 16:56:45 +01:00
882072cf30 Fixed resource leaks 2014-08-24 03:51:00 +02:00
7bd507d266 Disable client state in OpenGL example after rendering.
Using the example code in another application that has other rendering
code can cause rendering bugs or memory access errors if client state
is not disabled.
2014-08-22 16:00:38 -05:00
1ff104641a Web FAQ 2014-08-20 18:12:08 +01:00
3b8d1ec207 Update README.md - skinning 2014-08-20 17:56:23 +01:00
e9e1fd2b3c Added screenshot for web 2014-08-20 17:46:49 +01:00
6062d18cf9 Added basic sizes edition in the style editor 2014-08-20 17:42:53 +01:00
05f0993616 stb_textedit 1.4 fix signed/unsigned warnings 2014-08-20 10:43:08 +01:00
6dd2b13220 Merge branch 'Dadeos-compilation_warnings' 2014-08-20 10:41:06 +01:00
5864c45fe3 Fix type conversion compiler warnings (from dadeos) 2014-08-20 10:40:31 +01:00
4bc3642bdb Todo list 2014-08-20 10:19:05 +01:00
a3f32381c4 Fix mismatched static declaration warning 2014-08-19 12:51:13 +01:00
67f17a644c Converted all Tabs to Spaces
Argh
2014-08-19 12:45:34 +01:00
e807d97089 Exposed CalcTextSize(), GetCursorScreenPos() for more advanced fiddling 2014-08-19 12:39:30 +01:00
23d156908d Added an assertion 2014-08-19 12:27:34 +01:00
42d4b4be6a Converted all Tabs to Spaces (git diff -w shows an empty diff) 2014-08-19 12:09:13 +01:00
8 changed files with 5170 additions and 5104 deletions

View File

@ -30,6 +30,22 @@ The Immediate Mode GUI paradigm may at first appear unusual to some users. This
- [Jari Komppa's tutorial on building an ImGui library](http://iki.fi/sol/imgui/).
- [Casey Muratori's original video that popularized the concept](https://mollyrocket.com/861).
Frequently Asked Question
-------------------------
<b>How do you use ImGui on a platform that may not have a mouse and keyboard?</b>
I recommend using [Synergy](http://synergy-project.org) and the uSynergy.c micro client to share your mouse and keyboard. This way you can seemingly use your PC input devices on a video game console or a tablet. ImGui was also designed to function with touch inputs if you increase the padding of widgets to compensate for the lack of precision of touch devices, but it is recommended you use a mouse to allow optimising for screen real-estate.
<b>Can you create elaborate/serious tools with ImGui?</b>
Yes. I have written data browsers, debuggers, profilers and all sort of non-trivial tools with the library. There's no reason you cannot, and in my experience the simplicity of the API is very empowering. However note that ImGui is very programmer centric and the immediate-mode GUI paradigm might requires a bit of adaptation before you can realize its full potential.
<b>Can you reskin the look of ImGui?</b>
Yes, you can alter the look of the interface to some degree: changing colors, sizes and padding, font. However, as ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. The example below uses modified settings to create a more compact UI with different colors:
![skinning screenshot 1](/web/skinning_sample_01.png?raw=true)
Credits
-------

View File

@ -61,6 +61,9 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
}
}
glDisable(GL_SCISSOR_TEST);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
static const char* ImImpl_GetClipboardTextFn()

136
imgui.cpp
View File

@ -141,6 +141,7 @@
- text edit: pasting text into a number box should filter the characters the same way direct input does
- text edit: allow code to catch user pressing Return (perhaps through disable live edit? so only Return apply the final value, also allow catching Return if value didn't changed)
- settings: write more decent code to allow saving/loading new fields
- settings: api for per-tool simple persistant data (bool,int,float) in .ini file
- log: be able to right-click and log a window or tree-node into tty/file/clipboard?
- filters: set a current filter that tree node can automatically query to hide themselves
- filters: handle wildcards (with implicit leading/trailing *), regexps
@ -179,7 +180,6 @@ namespace ImGui
static bool ButtonBehaviour(const ImGuiAabb& bb, const ImGuiID& id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, bool repeat = false);
static void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f);
static void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, const bool hide_text_after_hash = true);
static ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, const bool hide_text_after_hash = true);
static void LogText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL);
static void ItemSize(ImVec2 size, ImVec2* adjust_start_offset = NULL);
@ -378,7 +378,7 @@ static ImU32 crc32(const void* data, size_t data_size, ImU32 seed = 0)
{
ImU32 crc = i;
for (ImU32 j = 0; j < 8; j++)
crc = (crc >> 1) ^ (-int(crc & 1) & polynomial);
crc = (crc >> 1) ^ (ImU32(-int(crc & 1)) & polynomial);
crc32_lut[i] = crc;
}
}
@ -396,16 +396,14 @@ static size_t ImFormatString(char* buf, size_t buf_size, const char* fmt, ...)
int w = vsnprintf(buf, buf_size, fmt, args);
va_end(args);
buf[buf_size-1] = 0;
if (w == -1) w = (int)buf_size;
return w;
return (w == -1) ? buf_size : (size_t)w;
}
static size_t ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args)
{
int w = vsnprintf(buf, buf_size, fmt, args);
buf[buf_size-1] = 0;
if (w == -1) w = (int)buf_size;
return w;
return (w == -1) ? buf_size : (size_t)w;
}
static ImU32 ImConvertColorFloat4ToU32(const ImVec4& in)
@ -727,6 +725,7 @@ static void RegisterAliveId(const ImGuiID& id)
//-----------------------------------------------------------------------------
// Helper: Key->value storage
void ImGuiStorage::Clear()
{
Data.clear();
@ -799,6 +798,7 @@ void ImGuiStorage::SetAllInt(int v)
//-----------------------------------------------------------------------------
// Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]"
ImGuiTextFilter::ImGuiTextFilter()
{
InputBuf[0] = 0;
@ -890,6 +890,7 @@ bool ImGuiTextFilter::PassFilter(const char* val) const
//-----------------------------------------------------------------------------
// Helper: Text buffer for logging/accumulating text
void ImGuiTextBuffer::append(const char* fmt, ...)
{
va_list args;
@ -900,13 +901,13 @@ void ImGuiTextBuffer::append(const char* fmt, ...)
return;
const size_t write_off = Buf.size();
if (write_off + len >= Buf.capacity())
if (write_off + (size_t)len >= Buf.capacity())
Buf.reserve(Buf.capacity() * 2);
Buf.resize(write_off + (size_t)len);
va_start(args, fmt);
ImFormatStringV(&Buf[write_off] - 1, len+1, fmt, args);
ImFormatStringV(&Buf[write_off] - 1, (size_t)len+1, fmt, args);
va_end(args);
}
@ -1051,14 +1052,24 @@ static void LoadSettings()
if ((f = fopen(filename, "rt")) == NULL)
return;
if (fseek(f, 0, SEEK_END))
{
fclose(f);
return;
long f_size = ftell(f);
if (f_size == -1)
}
const long f_size_signed = ftell(f);
if (f_size_signed == -1)
{
fclose(f);
return;
}
size_t f_size = (size_t)f_size_signed;
if (fseek(f, 0, SEEK_SET))
{
fclose(f);
return;
}
char* f_data = new char[f_size+1];
f_size = (long)fread(f_data, 1, f_size, f); // Text conversion alter read size so let's not be fussy about return value
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)
{
@ -1575,7 +1586,7 @@ static void RenderCollapseTriangle(ImVec2 p_min, bool open, float scale = 1.0f,
window->DrawList->AddTriangleFilled(a, b, c, window->Color(ImGuiCol_Border));
}
static ImVec2 CalcTextSize(const char* text, const char* text_end, const bool hide_text_after_hash)
ImVec2 CalcTextSize(const char* text, const char* text_end, const bool hide_text_after_hash)
{
ImGuiWindow* window = GetCurrentWindow();
@ -2345,7 +2356,7 @@ const char* GetStyleColorName(ImGuiCol idx)
case ImGuiCol_PlotLines: return "PlotLines";
case ImGuiCol_PlotLinesHovered: return "PlotLinesHovered";
case ImGuiCol_PlotHistogram: return "PlotHistogram";
case ImGuiCol_PlotHistogramHovered: return "ImGuiCol_PlotHistogramHovered";
case ImGuiCol_PlotHistogramHovered: return "PlotHistogramHovered";
case ImGuiCol_TextSelectedBg: return "TextSelectedBg";
case ImGuiCol_TooltipBg: return "TooltipBg";
}
@ -2441,6 +2452,12 @@ void SetCursorPos(const ImVec2& pos)
window->DC.CursorPos = window->Pos + pos;
}
ImVec2 GetCursorScreenPos()
{
ImGuiWindow* window = GetCurrentWindow();
return window->DC.CursorPos;
}
void SetScrollPosHere()
{
ImGuiWindow* window = GetCurrentWindow();
@ -2495,6 +2512,7 @@ void TextUnformatted(const char* text, const char* text_end)
if (window->SkipItems)
return;
IM_ASSERT(text != NULL);
const char* text_begin = text;
if (text_end == NULL)
text_end = text + strlen(text);
@ -3002,7 +3020,7 @@ void PushID(const void* ptr_id)
window->IDStack.push_back(window->GetID(ptr_id));
}
void PushID(int int_id)
void PushID(const int int_id)
{
const void* ptr_id = (void*)(intptr_t)int_id;
ImGuiWindow* window = GetCurrentWindow();
@ -3356,7 +3374,7 @@ enum ImGuiPlotType
static float PlotGetValue(const float* values, size_t stride, int idx)
{
float v = *(float*)((unsigned char*)values + idx * stride);
const float v = *(float*)((unsigned char*)values + (size_t)idx * stride);
return v;
}
@ -3609,14 +3627,14 @@ void STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int idx, int n) { c
bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int idx, const char* new_text, int new_text_len)
{
char* buf_end = obj->Text + obj->BufSize;
const int text_len = (int)strlen(obj->Text);
const size_t text_len = strlen(obj->Text);
if (new_text_len > buf_end - (obj->Text + text_len + 1))
return false;
memmove(obj->Text + idx + new_text_len, obj->Text + idx, text_len - idx);
memcpy(obj->Text + idx, new_text, new_text_len);
obj->Text[text_len + new_text_len] = 0;
memmove(obj->Text + (size_t)idx + new_text_len, obj->Text + (size_t)idx, text_len - (size_t)idx);
memcpy(obj->Text + (size_t)idx, new_text, (size_t)new_text_len);
obj->Text[text_len + (size_t)new_text_len] = 0;
return true;
}
@ -4059,7 +4077,7 @@ static bool Combo_ArrayGetter(void* data, int idx, const char** out_text)
bool Combo(const char* label, int* current_item, const char** items, int items_count, int popup_height_items)
{
bool value_changed = Combo(label, current_item, Combo_ArrayGetter, (void*)items, items_count, popup_height_items);
const bool value_changed = Combo(label, current_item, Combo_ArrayGetter, (void*)items, items_count, popup_height_items);
return value_changed;
}
@ -4132,7 +4150,7 @@ bool Combo(const char* label, int* current_item, bool (*items_getter)(void*, int
ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x);
ImGui::TextUnformatted(label, FindTextDisplayEnd(label));
ImGui::PushID(id);
ImGui::PushID((int)id);
bool menu_toggled = false;
if (hovered)
{
@ -4540,7 +4558,7 @@ float GetColumnOffset(int column_index)
if (column_index < 0)
column_index = window->DC.ColumnCurrent;
const ImGuiID column_id = ImGuiID(window->DC.ColumnsSetID + column_index);
const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index);
RegisterAliveId(column_id);
const float default_t = column_index / (float)window->DC.ColumnsCount;
const float t = (float)window->StateStorage.GetInt(column_id, (int)(default_t * 8096)) / 8096; // Cheaply store our floating point value inside the integer (could store an union into the map?)
@ -4556,7 +4574,7 @@ void SetColumnOffset(int column_index, float offset)
if (column_index < 0)
column_index = window->DC.ColumnCurrent;
const ImGuiID column_id = ImGuiID(window->DC.ColumnsSetID + column_index);
const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index);
const float t = (offset - window->DC.ColumnStartX) / (window->Size.x - g.Style.ScrollBarWidth - window->DC.ColumnStartX);
window->StateStorage.SetInt(column_id, (int)(t*8096));
}
@ -4606,7 +4624,7 @@ void Columns(int columns_count, const char* id, bool border)
{
float x = window->Pos.x + GetColumnOffset(i);
const ImGuiID column_id = ImGuiID(window->DC.ColumnsSetID + i);
const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(i);
const ImGuiAabb column_aabb(ImVec2(x-4,y1),ImVec2(x+4,y2));
if (IsClipped(column_aabb))
@ -4833,7 +4851,7 @@ void ImDrawList::AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, i
if (tris)
{
ReserveVertices((a_max-a_min) * 3);
ReserveVertices((unsigned int)(a_max-a_min) * 3);
for (int a = a_min; a < a_max; a++)
{
AddVtx(center + circle_vtx[a % IM_ARRAYSIZE(circle_vtx)] * rad, col);
@ -4843,7 +4861,7 @@ void ImDrawList::AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, i
}
else
{
ReserveVertices((a_max-a_min) * 6);
ReserveVertices((unsigned int)(a_max-a_min) * 6);
for (int a = a_min; a < a_max; a++)
AddVtxLine(center + circle_vtx[a % IM_ARRAYSIZE(circle_vtx)] * rad, center + circle_vtx[(a+1) % IM_ARRAYSIZE(circle_vtx)] * rad, col);
}
@ -4954,7 +4972,7 @@ void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int nu
if ((col >> 24) == 0)
return;
ReserveVertices(num_segments*6);
ReserveVertices((unsigned int)num_segments*6);
const float a_step = 2*PI/(float)num_segments;
float a0 = 0.0f;
for (int i = 0; i < num_segments; i++)
@ -4970,7 +4988,7 @@ void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col,
if ((col >> 24) == 0)
return;
ReserveVertices(num_segments*3);
ReserveVertices((unsigned int)num_segments*3);
const float a_step = 2*PI/(float)num_segments;
float a0 = 0.0f;
for (int i = 0; i < num_segments; i++)
@ -4992,17 +5010,17 @@ void ImDrawList::AddText(ImFont font, float font_size, const ImVec2& pos, ImU32
text_end = text_begin + strlen(text_begin);
// reserve vertices for worse case
const int char_count = (int)(text_end - text_begin);
const int vtx_count_max = char_count * 6;
const unsigned int char_count = (unsigned int)(text_end - text_begin);
const unsigned int vtx_count_max = char_count * 6;
const size_t vtx_begin = vtx_buffer.size();
ReserveVertices(vtx_count_max);
font->RenderText(font_size, pos, col, clip_rect_stack.back(), text_begin, text_end, vtx_write);
// give unused vertices
vtx_buffer.resize(vtx_write - &vtx_buffer.front());
const int vtx_count = (int)(vtx_buffer.size() - vtx_begin);
commands.back().vtx_count -= (vtx_count_max - vtx_count);
// give back unused vertices
vtx_buffer.resize((size_t)(vtx_write - &vtx_buffer.front()));
const size_t vtx_count = vtx_buffer.size() - vtx_begin;
commands.back().vtx_count -= (unsigned int)(vtx_count_max - vtx_count);
vtx_write -= (vtx_count_max - vtx_count);
}
@ -5043,8 +5061,10 @@ bool ImBitmapFont::LoadFromFile(const char* filename)
return false;
if (fseek(f, 0, SEEK_END))
return false;
if ((DataSize = (int)ftell(f)) == -1)
const long f_size = ftell(f);
if (f_size == -1)
return false;
DataSize = (size_t)f_size;
if (fseek(f, 0, SEEK_SET))
return false;
if ((Data = (unsigned char*)malloc(DataSize)) == NULL)
@ -5052,7 +5072,7 @@ bool ImBitmapFont::LoadFromFile(const char* filename)
fclose(f);
return false;
}
if ((int)fread(Data, 1, DataSize, f) != DataSize)
if (fread(Data, 1, DataSize, f) != DataSize)
{
fclose(f);
free(Data);
@ -5063,7 +5083,7 @@ bool ImBitmapFont::LoadFromFile(const char* filename)
return LoadFromMemory(Data, DataSize);
}
bool ImBitmapFont::LoadFromMemory(const void* data, int data_size)
bool ImBitmapFont::LoadFromMemory(const void* data, size_t data_size)
{
Data = (unsigned char*)data;
DataSize = data_size;
@ -5351,9 +5371,9 @@ static void SetClipboardTextFn_DefaultImpl(const char* text, const char* text_en
}
if (!text_end)
text_end = text + strlen(text);
GImGui.PrivateClipboard = (char*)malloc(text_end - text + 1);
memcpy(GImGui.PrivateClipboard, text, text_end - text);
GImGui.PrivateClipboard[text_end - text] = 0;
GImGui.PrivateClipboard = (char*)malloc((size_t)(text_end - text) + 1);
memcpy(GImGui.PrivateClipboard, text, (size_t)(text_end - text));
GImGui.PrivateClipboard[(size_t)(text_end - text)] = 0;
}
#endif
@ -5405,9 +5425,24 @@ void ShowStyleEditor(ImGuiStyle* ref)
*ref = g.Style;
}
ImGui::SliderFloat("Alpha", &style.Alpha, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI. But application code could have a toggle to switch between zero and non-zero.
ImGui::SliderFloat("Rounding", &style.WindowRounding, 0.0f, 16.0f, "%.0f");
ImGui::PushItemWidth(ImGui::GetWindowWidth()*0.55f);
if (ImGui::TreeNode("Sizes"))
{
ImGui::SliderFloat("Alpha", &style.Alpha, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI. But application code could have a toggle to switch between zero and non-zero.
ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f");
ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 16.0f, "%.0f");
ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f");
ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f");
ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f");
ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding, 0.0f, 20.0f, "%.0f");
ImGui::SliderFloat("TreeNodeSpacing", &style.TreeNodeSpacing, 0.0f, 20.0f, "%.0f");
ImGui::SliderFloat("ScrollBarWidth", &style.ScrollBarWidth, 0.0f, 20.0f, "%.0f");
ImGui::TreePop();
}
if (ImGui::TreeNode("Colors"))
{
static ImGuiColorEditMode edit_mode = ImGuiColorEditMode_RGB;
ImGui::RadioButton("RGB", &edit_mode, ImGuiColorEditMode_RGB);
ImGui::SameLine();
@ -5433,6 +5468,10 @@ void ShowStyleEditor(ImGuiStyle* ref)
}
ImGui::PopID();
}
ImGui::TreePop();
}
ImGui::PopItemWidth();
}
//-----------------------------------------------------------------------------
@ -5449,7 +5488,7 @@ void ShowTestWindow(bool* open)
static bool no_scrollbar = false;
static float fill_alpha = 0.65f;
const ImU32 layout_flags = (no_titlebar ? ImGuiWindowFlags_NoTitleBar : 0) | (no_border ? 0 : ImGuiWindowFlags_ShowBorders) | (no_resize ? ImGuiWindowFlags_NoResize : 0) | (no_move ? ImGuiWindowFlags_NoMove : 0) | (no_scrollbar ? ImGuiWindowFlags_NoScrollbar : 0);
const ImGuiWindowFlags layout_flags = (no_titlebar ? ImGuiWindowFlags_NoTitleBar : 0) | (no_border ? 0 : ImGuiWindowFlags_ShowBorders) | (no_resize ? ImGuiWindowFlags_NoResize : 0) | (no_move ? ImGuiWindowFlags_NoMove : 0) | (no_scrollbar ? ImGuiWindowFlags_NoScrollbar : 0);
ImGui::Begin("ImGui Test", open, ImVec2(550,680), fill_alpha, layout_flags);
ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);
@ -5614,7 +5653,7 @@ void ShowTestWindow(bool* open)
static bool pause;
static ImVector<float> values; if (values.empty()) { values.resize(100); memset(&values.front(), 0, values.size()*sizeof(float)); }
static int values_offset = 0;
static size_t values_offset = 0;
if (!pause)
{
// create dummy data at 60 hz
@ -5628,7 +5667,7 @@ void ShowTestWindow(bool* open)
phase += 0.10f*values_offset;
}
}
ImGui::PlotLines("Frame Times", &values.front(), (int)values.size(), values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,70));
ImGui::PlotLines("Frame Times", &values.front(), (int)values.size(), (int)values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,70));
ImGui::SameLine(); ImGui::Checkbox("pause", &pause);
ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,70));
@ -5818,6 +5857,11 @@ void ShowTestWindow(bool* open)
if (ImGui::CollapsingHeader("Filtering"))
{
static ImGuiTextFilter filter;
ImGui::Text("Filter usage:\n"
" \"\" display all lines\n"
" \"xxx\" display lines containing \"xxx\"\n"
" \"xxx,yyy\" display lines containing \"xxx\" or \"yyy\"\n"
" \"-xxx\" hide lines containing \"xxx\"");
filter.Draw();
const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" };
for (size_t i = 0; i < IM_ARRAYSIZE(lines); i++)
@ -5835,7 +5879,7 @@ void ShowTestWindow(bool* open)
ImGui::SameLine();
if (ImGui::Button("Add 1000 lines"))
{
for (size_t i = 0; i < 1000; i++)
for (int i = 0; i < 1000; i++)
log.append("%i The quick brown fox jumps over the lazy dog\n", lines+i);
lines += 1000;
}

14
imgui.h
View File

@ -107,7 +107,7 @@ public:
// Helpers at bottom of the file:
// - if (IMGUI_ONCE_UPON_A_FRAME) // Execute a block of code once per frame only
// - struct ImGuiTextFilter // Parse and apply text filter. In format "aaaaa[,bbbb][,ccccc]"
// - struct ImGuiTextFilter // Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]"
// - struct ImGuiTextBuffer // Text buffer for logging/accumulating text
// - struct ImGuiStorage // Custom key value storage (if you need to alter open/close states manually)
// - struct ImDrawList // Draw command list
@ -166,8 +166,9 @@ namespace ImGui
float GetColumnOffset(int column_index = -1);
void SetColumnOffset(int column_index, float offset);
float GetColumnWidth(int column_index = -1);
ImVec2 GetCursorPos(); // cursor position is relative to window position
ImVec2 GetCursorPos(); // cursor position relative to window position
void SetCursorPos(const ImVec2& pos); // "
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();
float GetTextLineHeight();
@ -251,6 +252,7 @@ namespace ImGui
int GetFrameCount();
const char* GetStyleColorName(ImGuiCol idx);
void GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size);
ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, const bool hide_text_after_hash = true);
}; // namespace ImGui
@ -447,7 +449,7 @@ private:
bool TryIsNewFrame() const { const int current_frame = ImGui::GetFrameCount(); if (LastFrame == current_frame) return false; LastFrame = current_frame; return true; }
};
// Helper: Parse and apply text filter. In format "aaaaa[,bbbb][,ccccc]"
// Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]"
struct ImGuiTextFilter
{
struct TextRange
@ -461,7 +463,7 @@ struct ImGuiTextFilter
const char* end() const { return e; }
bool empty() const { return b == e; }
char front() const { return *b; }
static bool isblank(char c) { return c == ' ' && c == '\t'; }
static bool isblank(char c) { return c == ' ' || c == '\t'; }
void trim_blanks() { while (b < e && isblank(*b)) b++; while (e > b && isblank(*(e-1))) e--; }
void split(char separator, ImVector<TextRange>& out);
};
@ -620,7 +622,7 @@ struct ImBitmapFont
#pragma pack(pop)
unsigned char* Data; // Raw data, content of .fnt file
int DataSize; //
size_t DataSize; //
bool DataOwned; //
const FntInfo* Info; // (point into raw data)
const FntCommon* Common; // (point into raw data)
@ -635,7 +637,7 @@ struct ImBitmapFont
ImBitmapFont();
~ImBitmapFont() { Clear(); }
bool LoadFromMemory(const void* data, int data_size);
bool LoadFromMemory(const void* data, size_t data_size);
bool LoadFromFile(const char* filename);
void Clear();
void BuildLookupTable();

View File

@ -1,4 +1,4 @@
// stb_textedit.h - v1.3 - public domain - Sean Barrett
// stb_textedit.h - v1.4 - public domain - Sean Barrett
// Development of this library was sponsored by RAD Game Tools
//
// This C header file implements the guts of a multi-line text-editing
@ -30,8 +30,9 @@
//
// VERSION HISTORY
//
// 1.3 (2013-06-19) fix mouse clicking to round to nearest char boundary
// 1.2 (2013-05-27) fix some RAD types that had crept into the new code
// 1.4 (2014-08-17) fix signed/unsigned warnings
// 1.3 (2014-06-19) fix mouse clicking to round to nearest char boundary
// 1.2 (2014-05-27) fix some RAD types that had crept into the new code
// 1.1 (2013-12-15) move-by-word (requires STB_TEXTEDIT_IS_SPACE )
// 1.0 (2012-07-26) improve documentation, initial public release
// 0.3 (2012-02-24) bugfixes, single-line mode; insert mode
@ -41,7 +42,7 @@
// ADDITIONAL CONTRIBUTORS
//
// Ulf Winklemann: move-by-word in 1.1
// Scott Graham: mouse selectiom bugfix in 1.3
// Scott Graham: mouse selection bugfix in 1.3
//
// USAGE
//
@ -445,7 +446,7 @@ static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state
static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
static void stb_text_makeundo_insert(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
typedef struct
@ -649,7 +650,7 @@ static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state
stb_textedit_delete_selection(str,state);
// try to insert the characters
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) {
stb_text_makeundo_insert(str, state, state->cursor, len);
stb_text_makeundo_insert(state, state->cursor, len);
state->cursor += len;
state->has_preferred_x = 0;
return 1;
@ -684,7 +685,7 @@ retry:
} else {
stb_textedit_delete_selection(str,state); // implicity clamps
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
stb_text_makeundo_insert(str, state, state->cursor, 1);
stb_text_makeundo_insert(state, state->cursor, 1);
++state->cursor;
state->has_preferred_x = 0;
}
@ -1007,13 +1008,13 @@ static void stb_textedit_discard_undo(StbUndoState *state)
int n = state->undo_rec[0].insert_length, i;
// delete n characters from all other records
state->undo_char_point = state->undo_char_point - (short) n; // vsnet05
memmove(state->undo_char, state->undo_char + n, state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE));
memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
for (i=0; i < state->undo_point; ++i)
if (state->undo_rec[i].char_storage >= 0)
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short) n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it
}
--state->undo_point;
memmove(state->undo_rec, state->undo_rec+1, state->undo_point*sizeof(state->undo_rec[0]));
memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
}
}
@ -1031,13 +1032,13 @@ static void stb_textedit_discard_redo(StbUndoState *state)
int n = state->undo_rec[k].insert_length, i;
// delete n characters from all other records
state->redo_char_point = state->redo_char_point + (short) n; // vsnet05
memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE));
memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
for (i=state->redo_point; i < k; ++i)
if (state->undo_rec[i].char_storage >= 0)
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05
}
++state->redo_point;
memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0]));
memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
}
}
@ -1203,7 +1204,7 @@ static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
s->redo_point++;
}
static void stb_text_makeundo_insert(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length)
{
stb_text_createundo(&state->undostate, where, 0, length);
}

BIN
web/skinning_sample_01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB