Compare commits

...

7 Commits
v1.03 ... v1.04

Author SHA1 Message Date
cda3aecc6a Fixed combo box (bug introduced earlier today) + adding bit of vertical padding in combo. 2014-08-13 19:26:25 +01:00
b6d1d85d86 Fixed scissoring in OpenGL example 2014-08-13 19:12:50 +01:00
9a426faf4f Added InputFloat2(), SliderFloat2() 2014-08-13 18:46:18 +01:00
b0d5600ffb Merge pull request #14 from Roflraging/constiteratorfix
Fix for gcc type qualifier warnings.
2014-08-13 18:40:18 +01:00
c52a54ef43 Fix for gcc type qualifier warnings.
With -Wall -Wextra -Werror, it is not possible to compile against
imgui.h due to const correctness violation in ImVector.
2014-08-13 11:57:37 -05:00
cc9d63b46a Fixed columns lines not being pixel aligned 2014-08-13 17:08:44 +01:00
d3ad5ce475 Update README.md 2014-08-13 13:23:37 +01:00
4 changed files with 96 additions and 27 deletions

View File

@ -1,11 +1,13 @@
ImGui
=====
ImGui is a bloat-free graphical user interface library for C++. It is portable, renderer agnostic and carries minimal amount of dependencies (only 3 files are needed). It is based on an "immediate" graphical user interface paradigm which allows you to build simple user interfaces with ease.
ImGui is a bloat-free graphical user interface library for C++. It outputs vertex buffers that you can render in your 3D-pipeline enabled application. It is portable, renderer agnostic and carries minimal amount of dependencies (only 3 files are needed). It is based on an "immediate" graphical user interface paradigm which allows you to build simple user interfaces with ease.
ImGui is designed to allow programmers to create "content creation" or "debug" tools (as opposed to tools for the average end-user). It favors simplicity and thus lacks certain features normally found in more high-level libraries, such as string localisation.
ImGui is designed to enable fast iteration and allow programmers to create "content creation" or "debug" tools (as opposed to tools for the average end-user). It favors simplicity and thus lacks certain features normally found in more high-level libraries, such as string localisation.
After ImGui is setup in your application, you can use it like in this example:
ImGui is particularly suited to integration in 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
After ImGui is setup in your engine, you can use it like in this example:
![screenshot of sample code alongside its output with ImGui](/web/code_sample_01.png?raw=true)

View File

@ -24,7 +24,7 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
//glEnable(GL_SCISSOR_TEST);
glEnable(GL_SCISSOR_TEST);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
@ -34,9 +34,11 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
glEnable(GL_TEXTURE_2D);
// Setup matrices
const float width = ImGui::GetIO().DisplaySize.x;
const float height = ImGui::GetIO().DisplaySize.y;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y, 0.0f, -1.0f, +1.0f);
glOrtho(0.0f, width, height, 0.0f, -1.0f, +1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
@ -53,7 +55,7 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
{
glScissor((int)pcmd->clip_rect.x, (int)pcmd->clip_rect.y, (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y));
glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y));
glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count);
vtx_offset += pcmd->vtx_count;
}

101
imgui.cpp
View File

@ -110,18 +110,19 @@
ISSUES AND TODO-LIST
- misc: merge ImVec4 / ImGuiAabb, they are essentially duplicate containers
- main: make IsHovered() more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes
- window: autofit is losing its purpose when user relies on any dynamic layout (window width multiplier, column). maybe just discard autofit?
- window: support horizontal scroll
- window: fix resize grip scaling along with Rounding style setting
- widgets: switching from "widget-label" to "label-widget" would make it more convenient to integrate widgets in trees
- widgets: clip text? hover clipped text shows it in a tooltip or in-place overlay
- main: make IsHovered() more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes
- main: make IsHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode?
- scrollbar: use relative mouse movement when first-clicking inside of scroll grab box.
- input number: optional range min/max
- input number: holding [-]/[+] buttons should increase the step non-linearly
- input number: rename Input*() to Input(), Slider*() to Slider() ?
- layout: clean up the InputFloat3/SliderFloat3/ColorEdit4 horrible layout code. item width should include frame padding, then we can have a generic horizontal layout helper.
- add input2/4 helper (once above layout helpers are in they'll be smaller)
- add input4 helper (once above layout helpers are in they'll be smaller)
- columns: declare column set (each column: fixed size, %, fill, distribute default size among fills)
- columns: columns header to act as button (~sort op) and allow resize/reorder
- columns: user specify columns size
@ -1036,7 +1037,7 @@ static void LoadSettings()
if (fseek(f, 0, SEEK_SET))
return;
char* f_data = new char[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
f_size = (long)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)
{
@ -1804,6 +1805,8 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin
window->SizeFull = size;
if (!(flags & ImGuiWindowFlags_ComboBox))
ImGui::PushClipRect(parent_window->ClipRectStack.back());
else
ImGui::PushClipRect(ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y));
}
else
{
@ -2074,16 +2077,8 @@ void End()
ImGuiWindow* window = g.CurrentWindow;
ImGui::Columns(1, "#CloseColumns");
ImGui::PopClipRect();
if (window->Flags & ImGuiWindowFlags_ChildWindow)
{
if (!(window->Flags & ImGuiWindowFlags_ComboBox))
ImGui::PopClipRect();
}
else
{
ImGui::PopClipRect();
}
ImGui::PopClipRect(); // inner window clip rectangle
ImGui::PopClipRect(); // outer window clip rectangle
// Select window for move/focus when we're done with all our widgets
ImGuiAabb bb(window->Pos, window->Pos+window->Size);
@ -3158,6 +3153,38 @@ bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* disp
return changed;
}
bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format, float power)
{
ImGuiState& g = GImGui;
ImGuiWindow* window = GetCurrentWindow();
if (window->Collapsed)
return false;
const ImGuiStyle& style = g.Style;
bool value_changed = false;
ImGui::PushID(label);
const int components = 2;
const float w_full = window->DC.ItemWidth.back();
const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f+style.ItemInnerSpacing.x)*(components-1)) / (float)components));
const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one+style.FramePadding.x*2.0f+style.ItemInnerSpacing.x)*(components-1)));
ImGui::PushItemWidth(w_item_one);
value_changed |= ImGui::SliderFloat("##X", &v[0], v_min, v_max, display_format, power);
ImGui::SameLine(0, 0);
ImGui::PopItemWidth();
ImGui::PushItemWidth(w_item_last);
value_changed |= ImGui::SliderFloat("##Y", &v[1], v_min, v_max, display_format, power);
ImGui::SameLine(0, 0);
ImGui::PopItemWidth();
ImGui::TextUnformatted(label, FindTextDisplayEnd(label));
ImGui::PopID();
return value_changed;
}
bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format, float power)
{
ImGuiState& g = GImGui;
@ -3168,7 +3195,6 @@ bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const
const ImGuiStyle& style = g.Style;
bool value_changed = false;
ImGui::PushID(label);
const int components = 3;
@ -3191,7 +3217,6 @@ bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const
ImGui::TextUnformatted(label, FindTextDisplayEnd(label));
ImGui::PopID();
return value_changed;
}
@ -3840,6 +3865,38 @@ bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlag
return value_changed;
}
bool InputFloat2(const char* label, float v[2], int decimal_precision)
{
ImGuiState& g = GImGui;
ImGuiWindow* window = GetCurrentWindow();
if (window->Collapsed)
return false;
const ImGuiStyle& style = g.Style;
bool value_changed = false;
ImGui::PushID(label);
const int components = 2;
const float w_full = window->DC.ItemWidth.back();
const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f+style.ItemInnerSpacing.x) * (components-1)) / (float)components));
const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one+style.FramePadding.x*2.0f+style.ItemInnerSpacing.x) * (components-1)));
ImGui::PushItemWidth(w_item_one);
value_changed |= ImGui::InputFloat("##X", &v[0], 0, 0, decimal_precision);
ImGui::SameLine(0, 0);
ImGui::PopItemWidth();
ImGui::PushItemWidth(w_item_last);
value_changed |= ImGui::InputFloat("##Y", &v[1], 0, 0, decimal_precision);
ImGui::SameLine(0, 0);
ImGui::PopItemWidth();
ImGui::TextUnformatted(label, FindTextDisplayEnd(label));
ImGui::PopID();
return value_changed;
}
bool InputFloat3(const char* label, float v[3], int decimal_precision)
{
ImGuiState& g = GImGui;
@ -3850,7 +3907,6 @@ bool InputFloat3(const char* label, float v[3], int decimal_precision)
const ImGuiStyle& style = g.Style;
bool value_changed = false;
ImGui::PushID(label);
const int components = 3;
@ -3873,7 +3929,6 @@ bool InputFloat3(const char* label, float v[3], int decimal_precision)
ImGui::TextUnformatted(label, FindTextDisplayEnd(label));
ImGui::PopID();
return value_changed;
}
@ -3982,6 +4037,7 @@ bool Combo(const char* label, int* current_item, bool (*items_getter)(void*, int
ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0);
ImGui::BeginChild("#ComboBox", popup_aabb.GetSize(), false, flags);
ImGuiWindow* child_window = GetCurrentWindow();
ImGui::Spacing();
bool combo_item_active = false;
combo_item_active |= (g.ActiveId == child_window->GetID("#SCROLLY"));
@ -4442,7 +4498,8 @@ void Columns(int columns_count, const char* id, bool border)
// Draw before resize so our items positioning are in sync with the line
const ImU32 col = window->Color(held ? ImGuiCol_ColumnActive : hovered ? ImGuiCol_ColumnHovered : ImGuiCol_Column);
window->DrawList->AddLine(ImVec2(x, y1), ImVec2(x, y2), col);
const float xi = (float)(int)x;
window->DrawList->AddLine(ImVec2(xi, y1), ImVec2(xi, y2), col);
if (held)
{
@ -5291,6 +5348,9 @@ void ShowTestWindow(bool* open)
ImGui::InputInt("input int", &i0);
ImGui::InputFloat("input float", &f0, 0.01f, 1.0f);
//static float vec2b[3] = { 0.10f, 0.20f };
//ImGui::InputFloat2("input float2", vec2b);
static float vec3b[3] = { 0.10f, 0.20f, 0.30f };
ImGui::InputFloat3("input float3", vec3b);
@ -5310,6 +5370,9 @@ void ShowTestWindow(bool* open)
static float angle = 0.0f;
ImGui::SliderAngle("angle", &angle);
//static float vec2a[3] = { 0.10f, 0.20f };
//ImGui::SliderFloat2("slider float2", vec2a, 0.0f, 1.0f);
static float vec3a[3] = { 0.10f, 0.20f, 0.30f };
ImGui::SliderFloat3("slider float3", vec3a, 0.0f, 1.0f);
@ -5342,7 +5405,7 @@ void ShowTestWindow(bool* open)
phase += 0.10f*values_offset;
}
}
ImGui::PlotLines("Frame Times", &values.front(), values.size(), values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,70));
ImGui::PlotLines("Frame Times", &values.front(), (int)values.size(), values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,70));
ImGui::SameLine(); ImGui::Checkbox("pause", &pause);
ImGui::PlotHistogram("Histogram", arr, ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,70));

View File

@ -85,9 +85,9 @@ public:
inline void clear() { if (_data) { _size = _capacity = 0; free(_data); _data = NULL; } }
inline iterator begin() { return _data; }
inline const iterator begin() const { return _data; }
inline const_iterator begin() const { return _data; }
inline iterator end() { return _data + _size; }
inline const iterator end() const { return _data + _size; }
inline const_iterator end() const { return _data + _size; }
inline value_type& front() { return at(0); }
inline const value_type& front() const { return at(0); }
inline value_type& back() { IM_ASSERT(_size > 0); return at(_size-1); }
@ -183,6 +183,7 @@ namespace ImGui
bool SmallButton(const char* label);
bool CollapsingHeader(const char* label, const char* str_id = NULL, const bool display_frame = true, const bool default_open = false);
bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
bool SliderAngle(const char* label, float* v, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f); // *v in radians
bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f");
@ -193,6 +194,7 @@ namespace ImGui
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);
bool InputFloat2(const char* label, float v[2], int decimal_precision = -1);
bool InputFloat3(const char* label, float v[3], int decimal_precision = -1);
bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100);
bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0);