mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-14 00:39:55 +02:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
cda3aecc6a | |||
b6d1d85d86 | |||
9a426faf4f | |||
b0d5600ffb | |||
c52a54ef43 | |||
cc9d63b46a | |||
d3ad5ce475 |
@ -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:
|
||||
|
||||

|
||||
|
||||
|
@ -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
101
imgui.cpp
@ -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));
|
||||
|
6
imgui.h
6
imgui.h
@ -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);
|
||||
|
Reference in New Issue
Block a user