Updated imgui.

This commit is contained in:
Branimir Karadžić 2015-05-31 11:31:56 -07:00
parent 44bf196b07
commit 5188958326
2 changed files with 238 additions and 150 deletions

View file

@ -1,4 +1,4 @@
// ImGui library v1.39 WIP
// ImGui library v1.40 WIP
// See ImGui::ShowTestWindow() for sample code.
// Read 'Programmer guide' below for notes on how to setup ImGui in your codebase.
// Get latest version at https://github.com/ocornut/imgui
@ -136,6 +136,8 @@
Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix.
Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
- 2015/05/31 (1.39) - renamed GetWindowCollapsed() to IsWindowCollapsed() for consistency. Kept inline redirection function (will obsolete).
- 2015/05/31 (1.39) - renamed IsRectClipped() to IsRectVisible() for consistency. Note that return value is opposite! Kept inline redirection function (will obsolete).
- 2015/05/27 (1.39) - removed the third 'repeat_if_held' parameter from Button() - sorry! it was rarely used and inconsistent. Use PushButtonRepeat(true) / PopButtonRepeat() to enable repeat on desired buttons.
- 2015/05/11 (1.39) - changed BeginPopup() API, takes a string identifier instead of a bool. ImGui needs to manage the open/closed state of popups. Call OpenPopup() to actually set the "opened" state of a popup. BeginPopup() returns true if the popup is opened.
- 2015/05/03 (1.39) - removed style.AutoFitPadding, using style.WindowPadding makes more sense (the default values were already the same).
@ -143,7 +145,7 @@
- 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API
- 2015/04/03 (1.38) - removed ImGuiCol_CheckHovered, ImGuiCol_CheckActive, replaced with the more general ImGuiCol_FrameBgHovered, ImGuiCol_FrameBgActive.
- 2014/04/03 (1.38) - removed support for passing -FLT_MAX..+FLT_MAX as the range for a SliderFloat(). Use DragFloat() or Inputfloat() instead.
- 2015/03/17 (1.36) - renamed GetItemRectMin()/GetItemRectMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function (will obsolete).
- 2015/03/17 (1.36) - renamed GetItemBoxMin()/GetItemBoxMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function (will obsolete).
- 2015/03/15 (1.36) - renamed style.TreeNodeSpacing to style.IndentSpacing, ImGuiStyleVar_TreeNodeSpacing to ImGuiStyleVar_IndentSpacing
- 2015/03/13 (1.36) - renamed GetWindowIsFocused() to IsWindowFocused(). Kept inline redirection function (will obsolete).
- 2015/03/08 (1.35) - renamed style.ScrollBarWidth to style.ScrollbarWidth
@ -360,6 +362,7 @@
- menus: local shortcuts, global shortcuts (github issue #126)
- menus: icons
- tabs
- separator: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y)
- gauge: various forms of gauge/loading bars widgets
- color: better color editor.
- plot: make it easier for user to draw extra stuff into the graph (e.g: draw basis, highlight certain points, 2d plots, multiple plots)
@ -964,7 +967,7 @@ static bool ImLoadFileToMemory(const char* filename, const char* file_open_mode,
enum ImGuiLayoutType_
{
ImGuiLayoutType_Vertical,
ImGuiLayoutType_Horizontal
ImGuiLayoutType_Horizontal // FIXME: this is in development, not exposed/functional as a generic feature yet.
};
enum ImGuiButtonFlags_
@ -1149,6 +1152,10 @@ struct ImGuiDrawContext
MenuBarOffsetX = 0.0f;
StateStorage = NULL;
LayoutType = ImGuiLayoutType_Vertical;
ItemWidth = 0.0f;
ButtonRepeat = false;
AllowKeyboardFocus = true;
TextWrapPos = 1.0f;
ColorEditMode = ImGuiColorEditMode_RGB;
memset(StackSizesBackup, 0, sizeof(StackSizesBackup));
@ -1332,6 +1339,7 @@ struct ImGuiState
ActiveIdIsAlive = false;
ActiveIdIsJustActivated = false;
ActiveIdIsFocusedOnly = false;
ActiveIdWindow = NULL;
MovedWindow = NULL;
SettingsDirtyTimer = 0.0f;
DisableHideTextAfterDoubleHash = 0;
@ -2134,16 +2142,18 @@ void ImGui::NewFrame()
// Are we using inputs? Tell user so they can capture/discard the inputs away from the rest of their application.
// When clicking outside of a window we assume the click is owned by the application and won't request capture.
int mouse_earliest_button_down = -1;
bool mouse_any_down = false;
for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++)
{
if (g.IO.MouseClicked[i])
g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL);
g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (!g.OpenedPopupStack.empty());
mouse_any_down |= g.IO.MouseDown[i];
if (g.IO.MouseDown[i])
if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[mouse_earliest_button_down] > g.IO.MouseClickedTime[i])
mouse_earliest_button_down = i;
}
bool mouse_owned_by_application = mouse_earliest_button_down != -1 && !g.IO.MouseDownOwned[mouse_earliest_button_down];
g.IO.WantCaptureMouse = (!mouse_owned_by_application && g.HoveredWindow != NULL) || (g.ActiveId != 0);
g.IO.WantCaptureMouse = (!mouse_owned_by_application && g.HoveredWindow != NULL) || (!mouse_owned_by_application && mouse_any_down) || (g.ActiveId != 0) || (!g.OpenedPopupStack.empty());
g.IO.WantCaptureKeyboard = (g.ActiveId != 0);
g.MouseCursor = ImGuiMouseCursor_Arrow;
@ -2720,6 +2730,7 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex
}
// Helper to calculate coarse clipping of large list of evenly sized items.
// NB: Prefer using the ImGuiListClipper higher-level helper if you can!
// If you are displaying thousands of items and you have a random access to the list, you can perform clipping yourself to save on CPU.
// {
// float item_height = ImGui::GetTextLineHeightWithSpacing();
@ -2734,7 +2745,6 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items
{
ImGuiState& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
if (g.LogEnabled)
{
// If logging is active, do not perform any clipping
@ -2752,7 +2762,6 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items
int end = (int)((clip_y2 - pos.y) / items_height);
start = ImClamp(start, 0, items_count);
end = ImClamp(end + 1, start, items_count);
*out_items_display_start = start;
*out_items_display_end = end;
}
@ -3171,35 +3180,33 @@ void ImGui::EndPopup()
ImGui::PopStyleVar();
}
bool ImGui::BeginPopupContextItem(const char* str_id, int button)
bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button)
{
if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(button))
if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(mouse_button))
ImGui::OpenPopup(str_id);
return ImGui::BeginPopup(str_id);
}
bool ImGui::BeginPopupContextWindow(bool in_empty_space_only, const char* str_id, int button)
bool ImGui::BeginPopupContextWindow(bool also_over_items, const char* str_id, int mouse_button)
{
if (!str_id) str_id = "window_context_menu";
if (ImGui::IsMouseHoveringWindow() && ImGui::IsMouseClicked(button))
if (!in_empty_space_only || !ImGui::IsAnyItemHovered())
if (ImGui::IsMouseHoveringWindow() && ImGui::IsMouseClicked(mouse_button))
if (also_over_items || !ImGui::IsAnyItemHovered())
ImGui::OpenPopup(str_id);
return ImGui::BeginPopup(str_id);
}
bool ImGui::BeginPopupContextVoid(const char* str_id, int button)
bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button)
{
if (!str_id) str_id = "void_context_menu";
if (!ImGui::IsMouseHoveringAnyWindow() && ImGui::IsMouseClicked(button))
if (!ImGui::IsMouseHoveringAnyWindow() && ImGui::IsMouseClicked(mouse_button))
ImGui::OpenPopup(str_id);
return ImGui::BeginPopup(str_id);
}
bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
{
ImGuiState& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow;
const ImVec2 content_max = window->Pos + ImGui::GetContentRegionMax();
@ -3209,13 +3216,13 @@ bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border,
{
if (size.x == 0.0f)
flags |= ImGuiWindowFlags_ChildWindowAutoFitX;
size.x = ImMax(content_max.x - cursor_pos.x, g.Style.WindowMinSize.x) - fabsf(size.x);
size.x = ImMax(content_max.x - cursor_pos.x, 4.0f) - fabsf(size.x); // Arbitrary minimum zeroish child size of 4.0f
}
if (size.y <= 0.0f)
{
if (size.y == 0.0f)
flags |= ImGuiWindowFlags_ChildWindowAutoFitY;
size.y = ImMax(content_max.y - cursor_pos.y, g.Style.WindowMinSize.y) - fabsf(size.y);
size.y = ImMax(content_max.y - cursor_pos.y, 4.0f) - fabsf(size.y);
}
if (border)
flags |= ImGuiWindowFlags_ShowBorders;
@ -3255,10 +3262,10 @@ void ImGui::EndChild()
// When using auto-filling child window, we don't provide full width/height to ItemSize so that it doesn't feed back into automatic size-fitting.
ImGuiState& g = *GImGui;
ImVec2 sz = ImGui::GetWindowSize();
if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitX)
sz.x = ImMax(g.Style.WindowMinSize.x, sz.x - g.Style.WindowPadding.x);
if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitX) // Arbitrary minimum zeroish child size of 4.0f
sz.x = ImMax(4.0f, sz.x - g.Style.WindowPadding.x);
if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitY)
sz.y = ImMax(g.Style.WindowMinSize.y, sz.y - g.Style.WindowPadding.y);
sz.y = ImMax(4.0f, sz.y - g.Style.WindowPadding.y);
ImGui::End();
@ -3439,6 +3446,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
g.CurrentWindowStack.push_back(window);
SetCurrentWindow(window);
CheckStacksSize(window, true);
IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow));
const int current_frame = ImGui::GetFrameCount();
bool window_was_visible = (window->LastFrameDrawn == current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on
@ -4413,10 +4421,9 @@ void ImGui::SetWindowCollapsed(bool collapsed, ImGuiSetCond cond)
SetWindowCollapsed(window, collapsed, cond);
}
bool ImGui::GetWindowCollapsed()
bool ImGui::IsWindowCollapsed()
{
ImGuiWindow* window = GetCurrentWindow();
return window->Collapsed;
return GImGui->CurrentWindow->Collapsed;
}
void ImGui::SetWindowCollapsed(const char* name, bool collapsed, ImGuiSetCond cond)
@ -4516,6 +4523,12 @@ float ImGui::GetTextLineHeightWithSpacing()
return g.FontSize + g.Style.ItemSpacing.y;
}
float ImGui::GetItemsLineHeightWithSpacing()
{
ImGuiState& g = *GImGui;
return g.FontSize + g.Style.FramePadding.y * 2.0f + g.Style.ItemSpacing.y;
}
ImDrawList* ImGui::GetWindowDrawList()
{
ImGuiWindow* window = GetCurrentWindow();
@ -7451,6 +7464,8 @@ bool ImGui::Selectable(const char* label, bool* p_selected, const ImVec2& size_a
bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return false;
const ImGuiStyle& style = ImGui::GetStyle();
const ImGuiID id = ImGui::GetID(label);
@ -7513,15 +7528,13 @@ bool ImGui::ListBox(const char* label, int* current_item, const char** items, in
bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return false;
if (!ImGui::ListBoxHeader(label, items_count, height_in_items))
return false;
// Assume all items have even height (= 1 line of text). If you need items of different or variable sizes you can create a custom version of ListBox() in your code without using the clipper.
bool value_changed = false;
for (int i = 0; i < items_count; i++)
ImGuiListClipper clipper(items_count, ImGui::GetTextLineHeightWithSpacing());
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
{
const bool item_selected = (i == *current_item);
const char* item_text;
@ -7536,7 +7549,7 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v
}
ImGui::PopID();
}
clipper.End();
ImGui::ListBoxFooter();
return value_changed;
}
@ -8029,10 +8042,11 @@ static bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when
return false;
}
bool ImGui::IsRectClipped(const ImVec2& size)
bool ImGui::IsRectVisible(const ImVec2& size)
{
ImGuiWindow* window = GetCurrentWindow();
return IsClippedEx(ImRect(window->DC.CursorPos, window->DC.CursorPos + size), NULL, true);
ImRect r(window->ClipRectStack.back());
return r.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size));
}
// Declare item bounding box for clipping and interaction.
@ -8925,6 +8939,7 @@ void ImFontAtlas::Clear()
ClearFonts();
}
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
void ImGui::GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size)
{
printf("GetDefaultFontData() is obsoleted in ImGui 1.30.\n");
@ -8935,6 +8950,7 @@ void ImGui::GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, co
if (png_size) *png_size = 0;
IM_ASSERT(false);
}
#endif
void ImFontAtlas::GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel)
{
@ -10027,6 +10043,7 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#pragma comment(lib, "user32")
// Win32 API clipboard implementation
static const char* GetClipboardTextFn_DefaultImpl()
@ -10235,7 +10252,6 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
filter.Draw("Filter colors", 200);
ImGui::BeginChild("#colors", ImVec2(0, 300), true);
ImGui::ColorEditMode(edit_mode);
for (int i = 0; i < ImGuiCol_COUNT; i++)
{
@ -10264,6 +10280,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
//-----------------------------------------------------------------------------
static void ShowExampleAppConsole(bool* opened);
static void ShowExampleAppLayout(bool* opened);
static void ShowExampleAppLongText(bool* opened);
static void ShowExampleAppAutoResize(bool* opened);
static void ShowExampleAppFixedOverlay(bool* opened);
@ -10272,6 +10289,13 @@ static void ShowExampleAppCustomRendering(bool* opened);
static void ShowExampleAppMainMenuBar();
static void ShowExampleMenuFile();
static void ShowHelpMarker(const char* desc)
{
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered())
ImGui::SetTooltip(desc);
}
// Demonstrate most ImGui features (big function!)
void ImGui::ShowTestWindow(bool* opened)
{
@ -10279,6 +10303,7 @@ void ImGui::ShowTestWindow(bool* opened)
static bool show_app_metrics = false;
static bool show_app_main_menu_bar = false;
static bool show_app_console = false;
static bool show_app_layout = false;
static bool show_app_long_text = false;
static bool show_app_auto_resize = false;
static bool show_app_fixed_overlay = false;
@ -10287,6 +10312,7 @@ void ImGui::ShowTestWindow(bool* opened)
if (show_app_metrics) ImGui::ShowMetricsWindow(&show_app_metrics);
if (show_app_main_menu_bar) ShowExampleAppMainMenuBar();
if (show_app_console) ShowExampleAppConsole(&show_app_console);
if (show_app_layout) ShowExampleAppLayout(&show_app_layout);
if (show_app_long_text) ShowExampleAppLongText(&show_app_long_text);
if (show_app_auto_resize) ShowExampleAppAutoResize(&show_app_auto_resize);
if (show_app_fixed_overlay) ShowExampleAppFixedOverlay(&show_app_fixed_overlay);
@ -10341,6 +10367,7 @@ void ImGui::ShowTestWindow(bool* opened)
ImGui::MenuItem("Metrics", NULL, &show_app_metrics);
ImGui::MenuItem("Main menu bar", NULL, &show_app_main_menu_bar);
ImGui::MenuItem("Console", NULL, &show_app_console);
ImGui::MenuItem("Simple layout", NULL, &show_app_layout);
ImGui::MenuItem("Long text display", NULL, &show_app_long_text);
ImGui::MenuItem("Auto-resizing window", NULL, &show_app_auto_resize);
ImGui::MenuItem("Simple overlay", NULL, &show_app_fixed_overlay);
@ -10533,7 +10560,7 @@ void ImGui::ShowTestWindow(bool* opened)
if (i > 0)
ImGui::SameLine();
ImGui::PushID(i);
int frame_padding = -1 + i; // -1 padding uses default padding
int frame_padding = -1 + i; // -1 = uses default padding
if (ImGui::ImageButton(tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/tex_w,32/tex_h), frame_padding))
pressed_count += 1;
ImGui::PopID();
@ -10647,11 +10674,8 @@ void ImGui::ShowTestWindow(bool* opened)
}
static float value = 0.5f;
ImGui::Text("Value = %.3f", value);
if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(1))
ImGui::OpenPopup("context menu");
ImGui::SameLine(); ImGui::Text("<-- right-click");
if (ImGui::BeginPopup("context menu"))
ImGui::Text("Value = %.3f (Context menu, right-click here)", value);
if (ImGui::BeginPopupContextItem("item context menu"))
{
if (ImGui::Selectable("Set to zero")) value = 0.0f;
if (ImGui::Selectable("Set to PI")) value = PI;
@ -10673,6 +10697,25 @@ void ImGui::ShowTestWindow(bool* opened)
ImGui::TreePop();
}
if (ImGui::TreeNode("Dragging"))
{
ImGui::TextWrapped("You can use ImGui::GetItemActiveDragDelta() to query for the dragged amount on any widget.");
ImGui::Button("Drag Me");
if (ImGui::IsItemActive())
{
// Draw a line between the button and the mouse cursor
ImDrawList* draw_list = ImGui::GetWindowDrawList();
draw_list->PushClipRectFullScreen();
draw_list->AddLine(ImGui::CalcItemRectClosestPoint(ImGui::GetIO().MousePos, true, -2.0f), ImGui::GetIO().MousePos, ImColor(ImGui::GetStyle().Colors[ImGuiCol_Button]), 4.0f);
draw_list->PopClipRect();
ImVec2 value_raw = ImGui::GetMouseDragDelta(0, 0.0f);
ImVec2 value_with_lock_threshold = ImGui::GetMouseDragDelta(0);
ImGui::SameLine(); ImGui::Text("Raw (%.1f, %.1f), WithLockThresold (%.1f, %.1f)", value_raw.x, value_raw.y, value_with_lock_threshold.x, value_with_lock_threshold.y);
}
ImGui::TreePop();
}
static bool check = true;
ImGui::Checkbox("checkbox", &check);
@ -10723,21 +10766,21 @@ void ImGui::ShowTestWindow(bool* opened)
ImGui::LabelText("label", "Value");
static int item = 1;
ImGui::Combo("combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0");
ImGui::Combo("combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); // Combo using values packed in a single constant string (for really quick combo)
const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK" };
static int item2 = -1;
ImGui::Combo("combo scroll", &item2, items, IM_ARRAYSIZE(items));
ImGui::Combo("combo scroll", &item2, items, IM_ARRAYSIZE(items)); // Combo using proper array. You can also pass a callback to retrieve array value, no need to create/copy an array just for that.
{
static char str0[128] = "Hello, world!";
static int i0=123;
static float f0=0.001f;
ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0));
ImGui::SameLine(); ImGui::TextDisabled("(?)"); if (ImGui::IsItemHovered()) ImGui::SetTooltip("Hold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n");
ImGui::SameLine(); ShowHelpMarker("Hold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n");
ImGui::InputInt("input int", &i0);
ImGui::SameLine(); ImGui::TextDisabled("(?)"); if (ImGui::IsItemHovered()) ImGui::SetTooltip("You can apply arithmetic operators +,*,/ on numerical values.\n e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n");
ImGui::SameLine(); ShowHelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n");
ImGui::InputFloat("input float", &f0, 0.01f, 1.0f);
@ -10746,29 +10789,23 @@ void ImGui::ShowTestWindow(bool* opened)
}
{
static int i1=50;
static int i2=42;
static int i1=50, i2=42;
ImGui::DragInt("drag int", &i1, 1);
ImGui::SameLine(); ImGui::TextDisabled("(?)"); if (ImGui::IsItemHovered()) ImGui::SetTooltip("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input text.");
ImGui::SameLine(); ShowHelpMarker("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input text.");
ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%.0f%%");
static float f1=1.00f;
static float f2=0.0067f;
static float f1=1.00f, f2=0.0067f;
ImGui::DragFloat("drag float", &f1, 1.0f);
ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns");
}
{
static int i1=0;
//static int i2=42;
ImGui::SliderInt("slider int", &i1, 0, 3);
ImGui::SameLine(); ImGui::TextDisabled("(?)"); if (ImGui::IsItemHovered()) ImGui::SetTooltip("CTRL+click to input value.");
ImGui::SameLine(); ShowHelpMarker("CTRL+click to input value.");
//ImGui::SliderInt("slider int -100..100", &i2, -100, 100);
static float f1=0.123f;
static float f2=0.0f;
static float f1=0.123f, f2=0.0f;
ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f");
ImGui::SliderFloat("slider log float", &f2, -10.0f, 10.0f, "%.4f", 3.0f);
static float angle = 0.0f;
@ -10778,7 +10815,7 @@ void ImGui::ShowTestWindow(bool* opened)
static float col1[3] = { 1.0f,0.0f,0.2f };
static float col2[4] = { 0.4f,0.7f,0.0f,0.5f };
ImGui::ColorEdit3("color 1", col1);
ImGui::SameLine(); ImGui::TextDisabled("(?)"); if (ImGui::IsItemHovered()) ImGui::SetTooltip("Click on the colored square to change edit mode. CTRL+click on individual component to input value.\n");
ImGui::SameLine(); ShowHelpMarker("Click on the colored square to change edit mode. CTRL+click on individual component to input value.\n");
ImGui::ColorEdit4("color 2", col2);
@ -10891,28 +10928,6 @@ void ImGui::ShowTestWindow(bool* opened)
ImGui::Indent();
ImGui::TreePop();
}
if (ImGui::TreeNode("Dragging"))
{
// You can use ImGui::GetItemActiveDragDelta() to query for the dragged amount on any widget.
static ImVec2 value_raw(0.0f, 0.0f);
static ImVec2 value_with_lock_threshold(0.0f, 0.0f);
ImGui::Button("Drag Me");
if (ImGui::IsItemActive())
{
value_raw = ImGui::GetMouseDragDelta(0, 0.0f);
value_with_lock_threshold = ImGui::GetMouseDragDelta(0);
//ImGui::SetTooltip("Delta: %.1f, %.1f", value.x, value.y);
// Draw a line between the button and the mouse cursor
ImDrawList* draw_list = ImGui::GetWindowDrawList();
draw_list->PushClipRectFullScreen();
draw_list->AddLine(ImGui::CalcItemRectClosestPoint(ImGui::GetIO().MousePos, true, -2.0f), ImGui::GetIO().MousePos, ImColor(ImGui::GetStyle().Colors[ImGuiCol_Button]), 4.0f);
draw_list->PopClipRect();
}
ImGui::SameLine(); ImGui::Text("Raw (%.1f, %.1f), WithLockThresold (%.1f, %.1f)", value_raw.x, value_raw.y, value_with_lock_threshold.x, value_with_lock_threshold.y);
ImGui::TreePop();
}
}
if (ImGui::CollapsingHeader("Graphs widgets"))
@ -10924,12 +10939,10 @@ void ImGui::ShowTestWindow(bool* opened)
static ImVector<float> values; if (values.empty()) { values.resize(90); memset(&values.front(), 0, values.size()*sizeof(float)); }
static size_t values_offset = 0;
if (!pause)
{
// create dummy data at fixed 60 hz rate
static float refresh_time = -1.0f;
if (ImGui::GetTime() > refresh_time + 1.0f/60.0f)
{
static float refresh_time = ImGui::GetTime(); // Create dummy data at fixed 60 hz rate for the demo
for (; ImGui::GetTime() > refresh_time + 1.0f/60.0f; refresh_time += 1.0f/60.0f)
{
refresh_time = ImGui::GetTime();
static float phase = 0.0f;
values[values_offset] = cosf(phase);
values_offset = (values_offset+1)%values.size();
@ -10973,13 +10986,11 @@ void ImGui::ShowTestWindow(bool* opened)
ImGui::TextWrapped("(Use ImGui::SameLine() to keep adding items to the right of the preceeding item)");
// Text
ImGui::Text("Two items: Hello");
ImGui::SameLine();
ImGui::Text("Two items: Hello"); ImGui::SameLine();
ImGui::TextColored(ImVec4(1,1,0,1), "Sailor");
// Adjust spacing
ImGui::Text("More spacing: Hello");
ImGui::SameLine(0, 20);
ImGui::Text("More spacing: Hello"); ImGui::SameLine(0, 20);
ImGui::TextColored(ImVec4(1,1,0,1), "Sailor");
// Button
@ -11045,8 +11056,6 @@ void ImGui::ShowTestWindow(bool* opened)
if (ImGui::TreeNode("Groups"))
{
ImGui::TextWrapped("(Using ImGui::BeginGroup()/EndGroup() to layout items)");
ImVec2 size;
ImGui::BeginGroup();
{
ImGui::BeginGroup();
@ -11063,12 +11072,12 @@ void ImGui::ShowTestWindow(bool* opened)
ImGui::SameLine();
ImGui::Button("EEE");
ImGui::EndGroup();
// Capture the group size and create widgets using the same size
size = ImGui::GetItemRectSize();
const float values[5] = { 0.5f, 0.20f, 0.80f, 0.60f, 0.25f };
ImGui::PlotHistogram("##values", values, IM_ARRAYSIZE(values), 0, NULL, 0.0f, 1.0f, size);
}
// Capture the group size and create widgets using the same size
ImVec2 size = ImGui::GetItemRectSize();
const float values[5] = { 0.5f, 0.20f, 0.80f, 0.60f, 0.25f };
ImGui::PlotHistogram("##values", values, IM_ARRAYSIZE(values), 0, NULL, 0.0f, 1.0f, size);
ImGui::Button("ACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f,size.y));
ImGui::SameLine();
ImGui::Button("REACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f,size.y));
@ -11152,7 +11161,7 @@ void ImGui::ShowTestWindow(bool* opened)
if (i == 50)
ImGui::NextColumn();
char buf[32];
ImFormatString(buf, IM_ARRAYSIZE(buf), "%08x", i*5731);
sprintf(buf, "%08x", i*5731);
ImGui::Button(buf);
}
ImGui::EndChild();
@ -11170,8 +11179,8 @@ void ImGui::ShowTestWindow(bool* opened)
ImGui::Text("Path"); ImGui::NextColumn();
ImGui::Text("Flags"); ImGui::NextColumn();
ImGui::Separator();
const char* names[3] = { "Robert", "Stephanie", "C64" };
const char* paths[3] = { "/path/robert", "/path/stephanie", "/path/computer" };
const char* names[3] = { "One", "Two", "Three" };
const char* paths[3] = { "/path/one", "/path/two", "/path/three" };
for (int i = 0; i < 3; i++)
{
ImGui::Text("%04d", i); ImGui::NextColumn();
@ -11316,14 +11325,14 @@ void ImGui::ShowTestWindow(bool* opened)
{
if (ImGui::TreeNode("Tabbing"))
{
ImGui::Text("Use TAB/SHIFT+TAB to cycle thru keyboard editable fields.");
ImGui::Text("Use TAB/SHIFT+TAB to cycle through keyboard editable fields.");
static char buf[32] = "dummy";
ImGui::InputText("1", buf, IM_ARRAYSIZE(buf));
ImGui::InputText("2", buf, IM_ARRAYSIZE(buf));
ImGui::InputText("3", buf, IM_ARRAYSIZE(buf));
ImGui::PushAllowKeyboardFocus(false);
ImGui::InputText("4 (tab skip)", buf, IM_ARRAYSIZE(buf));
//ImGui::SameLine(); ImGui::Text("(?)"); if (ImGui::IsHovered()) ImGui::SetTooltip("Use ImGui::PushAllowKeyboardFocus(bool)\nto disable tabbing through certain widgets.");
//ImGui::SameLine(); ShowHelperMarker("Use ImGui::PushAllowKeyboardFocus(bool)\nto disable tabbing through certain widgets.");
ImGui::PopAllowKeyboardFocus();
ImGui::InputText("5", buf, IM_ARRAYSIZE(buf));
ImGui::TreePop();
@ -11526,7 +11535,7 @@ static void ShowExampleMenuFile()
static void ShowExampleAppAutoResize(bool* opened)
{
if (!ImGui::Begin("Example: Auto-Resizing Window", opened, ImGuiWindowFlags_AlwaysAutoResize))
if (!ImGui::Begin("Example: Auto-resizing window", opened, ImGuiWindowFlags_AlwaysAutoResize))
{
ImGui::End();
return;
@ -11537,7 +11546,6 @@ static void ShowExampleAppAutoResize(bool* opened)
ImGui::SliderInt("Number of lines", &lines, 1, 20);
for (int i = 0; i < lines; i++)
ImGui::Text("%*sThis is line %d", i*4, "", i); // Pad with space to extend size horizontally
ImGui::End();
}
@ -11549,11 +11557,9 @@ static void ShowExampleAppFixedOverlay(bool* opened)
ImGui::End();
return;
}
ImGui::Text("Simple overlay\non the top-left side of the screen.");
ImGui::Separator();
ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y);
ImGui::End();
}
@ -11587,7 +11593,7 @@ static void ShowExampleAppManipulatingWindowTitle(bool* opened)
static void ShowExampleAppCustomRendering(bool* opened)
{
ImGui::SetNextWindowSize(ImVec2(300,350), ImGuiSetCond_FirstUseEver);
if (!ImGui::Begin("Example: Custom Rendering", opened))
if (!ImGui::Begin("Example: Custom rendering", opened))
{
ImGui::End();
return;
@ -11646,6 +11652,7 @@ static void ShowExampleAppCustomRendering(bool* opened)
ImGui::End();
}
// For the console example, here we are using a more C++ like approach of declaring a class to hold the data and the functions.
struct ExampleAppConsole
{
char InputBuf[256];
@ -11702,8 +11709,7 @@ struct ExampleAppConsole
ImGui::TextWrapped("This example implements a console with basic coloring, completion and history. A more elaborate implementation may want to store entries along with extra data such as timestamp, emitter, etc.");
ImGui::TextWrapped("Enter 'HELP' for help, press TAB to use text completion.");
// TODO: display from bottom
// TODO: clip manually
// TODO: display items starting from the bottom
if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.size()); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine();
if (ImGui::SmallButton("Add Dummy Error")) AddLog("[error] something went wrong"); ImGui::SameLine();
@ -11715,14 +11721,13 @@ struct ExampleAppConsole
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0));
static ImGuiTextFilter filter;
filter.Draw("Filter (\"incl,-excl\") (\"error\")", 180);
//if (ImGui::IsItemHovered()) ImGui::SetKeyboardFocusHere(-1); // Auto focus on hover
ImGui::PopStyleVar();
ImGui::Separator();
// Display every line as a separate entry so we can change their color or add custom widgets. If you only want raw text you can use ImGui::TextUnformatted(log.begin(), log.end());
// NB- if you have thousands of entries this approach may be too inefficient. You can seek and display only the lines that are visible - CalcListClipping() is a helper to compute this information.
// If your items are of variable size you may want to implement code similar to what CalcListClipping() does. Or split your data into fixed height items to allow random-seeking into your list.
ImGui::BeginChild("ScrollingRegion", ImVec2(0,-ImGui::GetTextLineHeightWithSpacing()*2));
ImGui::BeginChild("ScrollingRegion", ImVec2(0,-ImGui::GetItemsLineHeightWithSpacing()));
if (ImGui::BeginPopupContextWindow())
{
if (ImGui::Selectable("Clear")) ClearLog();
@ -11802,7 +11807,7 @@ struct ExampleAppConsole
}
}
static int TextEditCallbackStub(ImGuiTextEditCallbackData* data)
static int TextEditCallbackStub(ImGuiTextEditCallbackData* data) // In C++11 you are better off using lambdas for this sort of forwarding callbacks
{
ExampleAppConsole* console = (ExampleAppConsole*)data->UserData;
return console->TextEditCallback(data);
@ -11915,6 +11920,51 @@ static void ShowExampleAppConsole(bool* opened)
console.Run("Example: Console", opened);
}
static void ShowExampleAppLayout(bool* opened)
{
ImGui::SetNextWindowSize(ImVec2(500, 440), ImGuiSetCond_FirstUseEver);
if (ImGui::Begin("Example: Layout", opened, ImGuiWindowFlags_MenuBar))
{
if (ImGui::BeginMenuBar())
{
if (ImGui::BeginMenu("File"))
{
if (ImGui::MenuItem("Close")) *opened = false;
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
// left
static int selected = 0;
ImGui::BeginChild("left pane", ImVec2(150, 0), true);
for (int i = 0; i < 100; i++)
{
char label[128];
sprintf(label, "MyObject %d", i);
if (ImGui::Selectable(label, selected == i))
selected = i;
}
ImGui::EndChild();
ImGui::SameLine();
// right
ImGui::BeginGroup();
ImGui::BeginChild("item view", ImVec2(0, -ImGui::GetItemsLineHeightWithSpacing())); // Leave room for 1 line below us
ImGui::Text("MyObject: %d", selected);
ImGui::Separator();
ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ");
ImGui::EndChild();
ImGui::BeginChild("buttons");
if (ImGui::Button("Revert")) {}
ImGui::SameLine();
if (ImGui::Button("Save")) {}
ImGui::EndChild();
ImGui::EndGroup();
}
ImGui::End();
}
static void ShowExampleAppLongText(bool* opened)
{
ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver);
@ -11957,7 +12007,7 @@ static void ShowExampleAppLongText(bool* opened)
ImGui::PopStyleVar();
break;
case 2:
// Multiple calls to Text(), not clipped
// Multiple calls to Text(), not clipped (slow)
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0));
for (int i = 0; i < lines; i++)
ImGui::Text("%i The quick brown fox jumps over the lazy dog\n", i);

View file

@ -1,4 +1,4 @@
// ImGui library v1.39 WIP
// ImGui library v1.40 WIP
// See .cpp file for documentation.
// See ImGui::ShowTestWindow() for sample code.
// Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase.
@ -13,7 +13,7 @@
#include <stdlib.h> // NULL, malloc, free, qsort, atoi
#include <string.h> // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp
#define IMGUI_VERSION "1.39 WIP"
#define IMGUI_VERSION "1.40 WIP"
// Define assertion handler.
#ifndef IM_ASSERT
@ -80,6 +80,7 @@ struct ImVec4
// - struct ImGuiTextBuffer // Text buffer for logging/accumulating text
// - struct ImGuiStorage // Custom key value storage (if you need to alter open/close states manually)
// - struct ImGuiTextEditCallbackData // Shared state of ImGui::InputText() when using custom callbacks
// - struct ImGuiListClipper // Helper to manually clip large list of items.
// - struct ImColor // Helper functions to created packed 32-bit RGBA color values
// - struct ImDrawList // Draw command list
// - struct ImFontAtlas // Bake multiple fonts into a single texture, TTF font loader, bake glyphs into bitmap
@ -115,10 +116,10 @@ namespace ImGui
IMGUI_API ImFont* GetWindowFont();
IMGUI_API float GetWindowFontSize(); // size (also height in pixels) of current font with current scale applied
IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows
IMGUI_API ImVec2 GetWindowPos(); // you should rarely need/care about the window position, but it can be useful if you want to do your own drawing
IMGUI_API ImVec2 GetWindowSize(); // get current window position
IMGUI_API ImVec2 GetWindowPos(); // get current window position in screen space (useful if you want to do your own drawing via the DrawList api)
IMGUI_API ImVec2 GetWindowSize(); // get current window size
IMGUI_API float GetWindowWidth();
IMGUI_API bool GetWindowCollapsed();
IMGUI_API bool IsWindowCollapsed();
IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // set next window position - call before Begin()
IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond = 0); // set next window size. set to ImVec2(0,0) to force an auto-fit
@ -169,13 +170,13 @@ namespace ImGui
// Popup
IMGUI_API void OpenPopup(const char* str_id); // mark popup as open. popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). close childs popups if any. will close popup when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block.
IMGUI_API bool BeginPopup(const char* str_id); // return true if popup if opened and start outputting to it. only call EndPopup() if BeginPopup() returned true!
IMGUI_API bool BeginPopupContextItem(const char* str_id, int button = 1); // open popup when clicked on last item
IMGUI_API bool BeginPopupContextWindow(bool in_empty_space_only = false, const char* str_id = "window_context_menu", int button = 1); // open popup when clicked on current window
IMGUI_API bool BeginPopupContextVoid(const char* str_id = "void_context_menu", int button = 1); // open popup when clicked in void (no window)
IMGUI_API bool BeginPopupContextItem(const char* str_id, int mouse_button = 1); // open and begin popup when clicked on last item
IMGUI_API bool BeginPopupContextWindow(bool also_over_items = true, const char* str_id = NULL, int mouse_button = 1); // open and begin popup when clicked on current window
IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // open and begin popup when clicked in void (no window)
IMGUI_API void EndPopup();
IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup.
// Layout
// Cursor / Layout
IMGUI_API void BeginGroup(); // once closing a group it is seen as a single item (so you can use IsItemHovered() on a group, SameLine() between groups, etc.
IMGUI_API void EndGroup();
IMGUI_API void Separator(); // horizontal line
@ -201,7 +202,8 @@ namespace ImGui
IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute screen coordinates [0..io.DisplaySize]
IMGUI_API void AlignFirstTextHeightToWidgets(); // call once if the first item on the line is a Text() item and you want to vertically lower it to match subsequent (bigger) widgets
IMGUI_API float GetTextLineHeight(); // height of font == GetWindowFontSize()
IMGUI_API float GetTextLineHeightWithSpacing(); // spacing (in pixels) between 2 consecutive lines of text == GetWindowFontSize() + GetStyle().ItemSpacing.y
IMGUI_API float GetTextLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of text == GetWindowFontSize() + GetStyle().ItemSpacing.y
IMGUI_API float GetItemsLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of standard height widgets == GetWindowFontSize() + GetStyle().FramePadding.y*2 + GetStyle().ItemSpacing.y
// ID scopes
// If you are creating widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them
@ -252,19 +254,6 @@ namespace ImGui
IMGUI_API 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));
IMGUI_API void PlotHistogram(const char* label, float (*values_getter)(void* data, int idx), void* data, 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));
// Widgets: Sliders (tip: ctrl+click on a slider to input text)
IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix. Use power!=1.0 for logarithmic sliders
IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
IMGUI_API bool SliderAngle(const char* label, float* v_rad, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f);
IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f");
IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format = "%.0f");
IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format = "%.0f");
IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format = "%.0f");
IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f");
// Widgets: Drags (tip: ctrl+click on a drag box to input text)
IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); // If v_min >= v_max we have no bound
IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f);
@ -286,6 +275,19 @@ namespace ImGui
IMGUI_API bool InputInt3(const char* label, int v[3], ImGuiInputTextFlags extra_flags = 0);
IMGUI_API bool InputInt4(const char* label, int v[4], ImGuiInputTextFlags extra_flags = 0);
// Widgets: Sliders (tip: ctrl+click on a slider to input text)
IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix. Use power!=1.0 for logarithmic sliders
IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
IMGUI_API bool SliderAngle(const char* label, float* v_rad, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f);
IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f");
IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format = "%.0f");
IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format = "%.0f");
IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format = "%.0f");
IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f");
// Widgets: Trees
IMGUI_API bool TreeNode(const char* str_label_id); // if returning 'true' the node is open and the user is responsible for calling TreePop
IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...); // "
@ -309,14 +311,14 @@ namespace ImGui
// Widgets: Menus
IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar. only call EndMainMenuBar() if this returns true!
IMGUI_API void EndMainMenuBar();
IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window. only call EndMenuBar() if this returns true!
IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set). only call EndMenuBar() if this returns true!
IMGUI_API void EndMenuBar();
IMGUI_API bool BeginMenu(const char* label, bool enabled = true); // create a sub-menu entry. only call EndMenu() if this returns true!
IMGUI_API void EndMenu();
IMGUI_API bool MenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true); // return true when activated. shortcuts are displayed for convenience but not processed by ImGui
IMGUI_API bool MenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true); // return true when activated. shortcuts are displayed for convenience but not processed by ImGui at the moment
IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL
// Widgets: Value() Helpers. Output single value in "name: value" format (tip: freely declare your own within the ImGui namespace!)
// Widgets: Value() Helpers. Output single value in "name: value" format (tip: freely declare more in your code to handle your types. you can add functions to the ImGui namespace)
IMGUI_API void Value(const char* prefix, bool b);
IMGUI_API void Value(const char* prefix, int v);
IMGUI_API void Value(const char* prefix, unsigned int v);
@ -337,15 +339,15 @@ namespace ImGui
IMGUI_API bool IsItemHoveredRect(); // was the last item hovered by mouse? even if another item is active while we are hovering this
IMGUI_API bool IsItemActive(); // was the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false)
IMGUI_API bool IsItemVisible();
IMGUI_API bool IsAnyItemHovered(); //
IMGUI_API bool IsAnyItemActive(); //
IMGUI_API bool IsAnyItemHovered();
IMGUI_API bool IsAnyItemActive();
IMGUI_API ImVec2 GetItemRectMin(); // get bounding rect of last item in screen space
IMGUI_API ImVec2 GetItemRectMax(); // "
IMGUI_API ImVec2 GetItemRectSize(); // "
IMGUI_API bool IsWindowFocused(); // is current window focused (differentiate child windows from each others)
IMGUI_API bool IsRootWindowFocused(); // is current root window focused
IMGUI_API bool IsRootWindowFocused(); // is current root window focused (top parent window in case of child windows)
IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused
IMGUI_API bool IsRectClipped(const ImVec2& size); // test if rectangle of given size starting from cursor pos is out of clipping region. to perform coarse clipping on user's side (as an optimization)
IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle of given size starting from cursor pos is visible (not clipped). to perform coarse clipping on user's side (as an optimization)
IMGUI_API bool IsKeyDown(int key_index); // key_index into the keys_down[512] array, imgui doesn't know the semantic of each entry
IMGUI_API bool IsKeyPressed(int key_index, bool repeat = true); // "
IMGUI_API bool IsMouseDown(int button);
@ -366,7 +368,7 @@ namespace ImGui
IMGUI_API const char* GetStyleColName(ImGuiCol idx);
IMGUI_API ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f); // utility to find the closest point the last item bounding rectangle edge. useful to visually link items
IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // helper to manually clip large list of items. see comments in implementation
IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // calculate coarse clipping for large list of evenly sized items. Prefer using the ImGuiListClipper higher-level helper if you can.
IMGUI_API void BeginChildFrame(ImGuiID id, const ImVec2& size); // helper to create a child window / scrolling region that looks like a normal widget frame
IMGUI_API void EndChildFrame();
@ -375,24 +377,28 @@ namespace ImGui
IMGUI_API void ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v);
IMGUI_API void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b);
// Proxy functions to access the MemAllocFn/MemFreeFn pointers in ImGui::GetIO()
// Helpers functions to access the MemAllocFn/MemFreeFn pointers in ImGui::GetIO()
IMGUI_API void* MemAlloc(size_t sz);
IMGUI_API void MemFree(void* ptr);
// Internal state access - if you want to share ImGui state between modules (e.g. DLL) or allocate it yourself
// Internal state/context access - if you want to use multiple ImGui context, or share context between modules (e.g. DLL), or allocate the memory yourself
IMGUI_API const char* GetVersion();
IMGUI_API void* GetInternalState();
IMGUI_API size_t GetInternalStateSize();
IMGUI_API void SetInternalState(void* state, bool construct = false);
// Obsolete (will be removed)
IMGUI_API void GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size); // OBSOLETE
static inline void OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpened(open, 0); } // OBSOLETE
static inline bool GetWindowIsFocused() { return ImGui::IsWindowFocused(); } // OBSOLETE
static inline ImVec2 GetItemBoxMin() { return GetItemRectMin(); } // OBSOLETE
static inline ImVec2 GetItemBoxMax() { return GetItemRectMax(); } // OBSOLETE
static inline bool IsClipped(const ImVec2& size) { return IsRectClipped(size); } // OBSOLETE
static inline bool IsMouseHoveringBox(const ImVec2& rect_min, const ImVec2& rect_max) { return IsMouseHoveringRect(rect_min, rect_max); } // OBSOLETE
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
IMGUI_API void GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size); // OBSOLETE 1.30+
static inline void OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpened(open, 0); } // OBSOLETE 1.34+
static inline bool GetWindowIsFocused() { return ImGui::IsWindowFocused(); } // OBSOLETE 1.36+
static inline bool GetWindowCollapsed() { return ImGui::IsWindowCollapsed(); } // OBSOLETE 1.39+
static inline ImVec2 GetItemBoxMin() { return GetItemRectMin(); } // OBSOLETE 1.36+
static inline ImVec2 GetItemBoxMax() { return GetItemRectMax(); } // OBSOLETE 1.36+
static inline bool IsClipped(const ImVec2& size) { return !IsRectVisible(size); } // OBSOLETE 1.38+
static inline bool IsRectClipped(const ImVec2& size) { return !IsRectVisible(size); } // OBSOLETE 1.39+
static inline bool IsMouseHoveringBox(const ImVec2& rect_min, const ImVec2& rect_max) { return IsMouseHoveringRect(rect_min, rect_max); } // OBSOLETE 1.36+
#endif
} // namespace ImGui
@ -409,7 +415,7 @@ enum ImGuiWindowFlags_
ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame
ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items
ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file
ImGuiWindowFlags_MenuBar = 1 << 9, // Has a menubar
ImGuiWindowFlags_MenuBar = 1 << 9, // Has a menu-bar
// [Internal]
ImGuiWindowFlags_ChildWindow = 1 << 20, // Don't use! For internal use by BeginChild()
ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 21, // Don't use! For internal use by BeginChild()
@ -898,6 +904,38 @@ struct ImColor
static ImColor HSV(float h, float s, float v, float a = 1.0f) { float r,g,b; ImGui::ColorConvertHSVtoRGB(h, s, v, r, g, b); return ImColor(r,g,b,a); }
};
// Helper: Manually clip large list of items.
// If you are displaying thousands of even spaced items and you have a random access to the list, you can perform clipping yourself to save on CPU.
// Usage:
// ImGuiListClipper clipper(count, ImGui::GetTextLineHeightWithSpacing());
// for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) // display only visible items
// ImGui::Text("line number %d", i);
// clipper.End();
struct ImGuiListClipper
{
float ItemsHeight;
int ItemsCount, DisplayStart, DisplayEnd;
ImGuiListClipper() { ItemsHeight = 0.0f; ItemsCount = DisplayStart = DisplayEnd = -1; }
ImGuiListClipper(int count, float height) { ItemsCount = -1; Begin(count, height); }
~ImGuiListClipper() { IM_ASSERT(ItemsCount == -1); } // user forgot to call End()
void Begin(int count, float height) // items_height: generally pass GetTextLineHeightWithSpacing() or GetItemsLineHeightWithSpacing()
{
IM_ASSERT(ItemsCount == -1);
ItemsCount = count;
ItemsHeight = height;
ImGui::CalcListClipping(ItemsCount, ItemsHeight, &DisplayStart, &DisplayEnd); // calculate how many to clip/display
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + DisplayStart * ItemsHeight); // advance cursor
}
void End()
{
IM_ASSERT(ItemsCount >= 0);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (ItemsCount - DisplayEnd) * ItemsHeight); // advance cursor
ItemsCount = -1;
}
};
//-----------------------------------------------------------------------------
// Draw List
// Hold a series of drawing commands. The user provides a renderer for ImDrawList.