merge with upstream

This commit is contained in:
Sepehr Taghdisian 2014-08-16 13:00:39 +04:30
commit 5240013c90
2 changed files with 182 additions and 94 deletions

241
imgui.cpp
View file

@ -109,6 +109,7 @@
ISSUES AND TODO-LIST
- misc: allow user to call NewFrame() multiple times without a render.
- misc: merge ImVec4 / ImGuiAabb, they are essentially duplicate containers
- 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
@ -130,7 +131,6 @@
- combo: turn child handling code into popup helper
- list selection, concept of a selectable "block" (that can be multiple widgets)
- menubar, menus
- plot: add a stride parameter?
- plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID)
- file selection widget -> build the tool in our codebase to improve model-dialog idioms (may or not lead to ImGui changes)
- slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt()
@ -150,6 +150,7 @@
- optimisation/render: use indexed rendering
- optimisation/render: move clip-rect to vertex data? would allow merging all commands
- optimisation/render: merge command-list of all windows into one command-list?
- optimisation/render: font exported by bmfont is not tight fit on vertical axis, incur unneeded pixel-shading cost.
- optimisation: turn some the various stack vectors into statically-sized arrays
- optimisation: better clipping for multi-component widgets
- optimisation: specialize for height based clipping first (assume widgets never go up + height tests before width tests?)
@ -182,7 +183,7 @@
namespace ImGui
{
static bool ButtonBehaviour(const ImGuiAabb& bb, const ImGuiID& id, bool* out_hovered = NULL, bool* out_held = NULL, bool repeat = false);
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);
@ -199,6 +200,7 @@ static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true);
static bool CloseWindowButton(bool* open = NULL);
static void FocusWindow(ImGuiWindow* window);
static ImGuiWindow* FindWindow(const char* name);
static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs);
}; // namespace ImGui
@ -249,7 +251,7 @@ ImGuiStyle::ImGuiStyle()
Colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f);
Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f);
Colors[ImGuiCol_Button] = ImVec4(0.67f, 0.40f, 0.40f, 0.60f);
Colors[ImGuiCol_ButtonHovered] = ImVec4(0.60f, 0.40f, 0.40f, 1.00f);
Colors[ImGuiCol_ButtonHovered] = ImVec4(0.67f, 0.40f, 0.40f, 1.00f);
Colors[ImGuiCol_ButtonActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f);
Colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f);
Colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f);
@ -1139,11 +1141,13 @@ static void SaveSettings()
return;
for (size_t i = 0; i != g.Settings.size(); i++)
{
const ImGuiIniData* ini = g.Settings[i];
fprintf(f, "[%s]\n", ini->Name);
fprintf(f, "Pos=%d,%d\n", (int)ini->Pos.x, (int)ini->Pos.y);
fprintf(f, "Size=%d,%d\n", (int)ini->Size.x, (int)ini->Size.y);
fprintf(f, "Collapsed=%d\n", ini->Collapsed);
const ImGuiIniData* settings = g.Settings[i];
if (settings->Pos.x == FLT_MAX)
continue;
fprintf(f, "[%s]\n", settings->Name);
fprintf(f, "Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y);
fprintf(f, "Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y);
fprintf(f, "Collapsed=%d\n", settings->Collapsed);
fprintf(f, "\n");
}
@ -1282,7 +1286,8 @@ void NewFrame()
else
{
// Scroll
window->NextScrollY -= g.IO.MouseWheel * window->FontSize() * 5.0f;
const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5;
window->NextScrollY -= g.IO.MouseWheel * window->FontSize() * scroll_lines;
}
}
@ -1404,7 +1409,7 @@ void Render()
ImGui::End();
// Sort the window list so that all child windows are after their parent
// When cannot do that on FocusWindow() because childs may not exist yet
// We cannot do that on FocusWindow() because childs may not exist yet
ImVector<ImGuiWindow*> sorted_windows;
sorted_windows.reserve(g.Windows.size());
for (size_t i = 0; i != g.Windows.size(); i++)
@ -1423,34 +1428,28 @@ void Render()
memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
}
// Render tooltip
if (g.Tooltip[0])
{
// Use a dummy window to render the tooltip
ImGui::BeginTooltip();
ImGui::TextUnformatted(g.Tooltip);
ImGui::EndTooltip();
}
// Gather windows to render
g.RenderDrawLists.resize(0);
for (size_t i = 0; i != g.Windows.size(); i++)
{
ImGuiWindow* window = g.Windows[i];
if (!window->Visible)
continue;
if (window->Flags & ImGuiWindowFlags_ChildWindow)
continue;
window->AddToRenderList();
if (window->Visible && (window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) == 0)
window->AddToRenderList();
}
// Render tooltip
if (g.Tooltip[0])
for (size_t i = 0; i != g.Windows.size(); i++)
{
// Use a dummy window to render the tooltip
ImGui::Begin("##Tooltip", NULL, ImVec2(0,0), 0.0f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_Tooltip);
ImGuiWindow* window = GetCurrentWindow();
//window->DrawList->Clear();
ImGui::PushClipRect(ImVec4(-9999,-9999,+9999,+9999), false);
const ImVec2 text_size = CalcTextSize(g.Tooltip, NULL, false);
const ImVec2 pos = g.IO.MousePos + ImVec2(32,16);
const ImGuiAabb bb(pos - g.Style.FramePadding*2, pos + text_size + g.Style.FramePadding*2);
ImGui::RenderFrame(bb.Min, bb.Max, window->Color(ImGuiCol_TooltipBg), false, g.Style.WindowRounding);
ImGui::RenderText(pos, g.Tooltip, NULL, false);
ImGui::PopClipRect();
ImGui::End();
window->AddToRenderList();
ImGuiWindow* window = g.Windows[i];
if (window->Visible && (window->Flags & ImGuiWindowFlags_Tooltip))
window->AddToRenderList();
}
// Render
@ -1733,7 +1732,7 @@ void SetTooltip(const char* fmt, ...)
va_end(args);
}
void SetNewWindowDefaultPos(ImVec2 pos)
void SetNewWindowDefaultPos(const ImVec2& pos)
{
ImGuiState& g = GImGui;
g.NewWindowDefaultPos = pos;
@ -1758,6 +1757,17 @@ static ImGuiWindow* FindWindow(const char* name)
return NULL;
}
void BeginTooltip()
{
ImGui::Begin("##Tooltip", NULL, ImVec2(0,0), 0.9f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_Tooltip);
}
void EndTooltip()
{
IM_ASSERT(GetCurrentWindow()->Flags & ImGuiWindowFlags_Tooltip);
ImGui::End();
}
void BeginChild(const char* str_id, ImVec2 size, bool border, ImGuiWindowFlags extra_flags)
{
ImGuiState& g = GImGui;
@ -1824,7 +1834,7 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin
ImGuiWindow *buff = GImGui.GuiWindowPool.alloc();
IM_ASSERT(buff);
if (flags & ImGuiWindowFlags_ChildWindow)
if (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip))
{
window = new(buff) ImGuiWindow(name, ImVec2(0,0), size);
}
@ -1859,12 +1869,21 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin
const bool first_begin_of_the_frame = (window->LastFrameDrawn != current_frame);
if (first_begin_of_the_frame)
{
// New windows appears in front
if (window->LastFrameDrawn < current_frame - 1)
ImGui::FocusWindow(window);
window->DrawList->Clear();
window->Visible = true;
// New windows appears in front
if (window->LastFrameDrawn < current_frame - 1)
{
ImGui::FocusWindow(window);
if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0)
{
// Hide for 1 frame while resizing
window->AutoFitFrames = 2;
window->Visible = false;
}
}
window->LastFrameDrawn = current_frame;
window->ClipRectStack.resize(0);
@ -1906,6 +1925,12 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin
}
}
// Tooltips always follow mouse
if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0)
{
window->PosFloat = g.IO.MousePos + ImVec2(32,16) - g.Style.FramePadding*2;
}
// Clamp into view
if (!(window->Flags & ImGuiWindowFlags_ChildWindow))
{
@ -1919,7 +1944,12 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin
{
window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y);
}
window->ItemWidthDefault = (float)(int)(window->Size.x > 0.0f ? window->Size.x * 0.65f : 250.0f);
// Default item width
if (window->Size.x > 0.0f && !(window->Flags & ImGuiWindowFlags_Tooltip))
window->ItemWidthDefault = (float)(int)(window->Size.x * 0.65f);
else
window->ItemWidthDefault = 200.0f;
// Prepare for focus requests
if (window->FocusIdxRequestNext == IM_INT_MAX || window->FocusIdxCounter == -1)
@ -1974,17 +2004,25 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin
{
window->Size = window->SizeFull;
// Draw resize grip
// Draw resize grip and resize
ImU32 resize_col = 0;
if (!(window->Flags & ImGuiWindowFlags_NoResize))
if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0)
{
if (window->AutoFitFrames > 0)
{
// Tooltip always resize
window->SizeFull = window->SizeContentsFit + g.Style.WindowPadding - ImVec2(0.0f, g.Style.ItemSpacing.y);
}
}
else if (!(window->Flags & ImGuiWindowFlags_NoResize))
{
const ImGuiAabb resize_aabb(window->Aabb().GetBR()-ImVec2(18,18), window->Aabb().GetBR());
const ImGuiID resize_id = window->GetID("#RESIZE");
bool hovered, held;
ButtonBehaviour(resize_aabb, resize_id, &hovered, &held);
ButtonBehaviour(resize_aabb, resize_id, &hovered, &held, true);
resize_col = window->Color(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip);
const ImVec2 size_auto_fit = ImClamp(window->SizeContentsFit + style.AutoFitPadding, style.WindowMinSize, g.IO.DisplaySize - style.AutoFitPadding);
ImVec2 size_auto_fit = ImClamp(window->SizeContentsFit + style.AutoFitPadding, style.WindowMinSize, g.IO.DisplaySize - style.AutoFitPadding);
if (window->AutoFitFrames > 0)
{
// Auto-fit only grows during the first few frames
@ -2049,7 +2087,7 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin
if (grab_size_y_norm < 1.0f)
{
const ImGuiID scrollbar_id = window->GetID("#SCROLLY");
ButtonBehaviour(scrollbar_bb, scrollbar_id, &hovered, &held);
ButtonBehaviour(scrollbar_bb, scrollbar_id, &hovered, &held, true);
if (held)
{
g.HoveredId = scrollbar_id;
@ -2130,7 +2168,7 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin
ImGui::PushClipRect(ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y));
}
// Innter clipping rectangle
// Inner clipping rectangle
// We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame
const ImGuiAabb title_bar_aabb = window->TitleBarAabb();
ImVec4 clip_rect(title_bar_aabb.Min.x+0.5f, title_bar_aabb.Max.y+0.5f, window->Aabb().Max.x-1.5f, window->Aabb().Max.y-1.5f);
@ -2235,7 +2273,7 @@ void PopAllowKeyboardFocus()
window->DC.AllowKeyboardFocus.pop_back();
}
void PushStyleColor(ImGuiCol idx, ImVec4 col)
void PushStyleColor(ImGuiCol idx, const ImVec4& col)
{
ImGuiState& g = GImGui;
ImGuiWindow* window = GetCurrentWindow();
@ -2323,10 +2361,15 @@ ImVec2 GetWindowPos()
return window->Pos;
}
void SetWindowPos(ImVec2 pos)
void SetWindowPos(const ImVec2& pos)
{
ImGuiWindow* window = GetCurrentWindow();
window->Pos = pos;
const ImVec2 old_pos = window->Pos;
window->PosFloat = pos;
window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y);
// If we happen to move the window while it is showing (which is a bad idea) let's at least offset the cursor
window->DC.CursorPos += (window->Pos - old_pos);
}
ImVec2 GetWindowSize()
@ -2381,10 +2424,10 @@ ImVec2 GetCursorPos()
return window->DC.CursorPos - window->Pos;
}
void SetCursorPos(ImVec2 p)
void SetCursorPos(const ImVec2& pos)
{
ImGuiWindow* window = GetCurrentWindow();
window->DC.CursorPos = window->Pos + p;
window->DC.CursorPos = window->Pos + pos;
}
void SetScrollPosHere()
@ -2424,6 +2467,16 @@ void Text(const char* fmt, ...)
va_end(args);
}
void TextColored(const ImVec4& col, const char* fmt, ...)
{
ImGui::PushStyleColor(ImGuiCol_Text, col);
va_list args;
va_start(args, fmt);
TextV(fmt, args);
va_end(args);
ImGui::PopStyleColor();
}
void TextUnformatted(const char* text, const char* text_end)
{
ImGuiState& g = GImGui;
@ -2563,7 +2616,7 @@ void LabelText(const char* label, const char* fmt, ...)
RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y), label);
}
static bool ButtonBehaviour(const ImGuiAabb& bb, const ImGuiID& id, bool* out_hovered, bool* out_held, bool repeat)
static bool ButtonBehaviour(const ImGuiAabb& bb, const ImGuiID& id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, bool repeat)
{
ImGuiState& g = GImGui;
ImGuiWindow* window = GetCurrentWindow();
@ -2573,13 +2626,16 @@ static bool ButtonBehaviour(const ImGuiAabb& bb, const ImGuiID& id, bool* out_ho
if (hovered)
{
g.HoveredId = id;
if (g.IO.MouseClicked[0])
if (allow_key_modifiers || (!g.IO.KeyCtrl && !g.IO.KeyShift))
{
g.ActiveId = id;
}
else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true))
{
pressed = true;
if (g.IO.MouseClicked[0])
{
g.ActiveId = id;
}
else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true))
{
pressed = true;
}
}
}
@ -2627,7 +2683,7 @@ bool Button(const char* label, ImVec2 size, bool repeat_when_held)
return false;
bool hovered, held;
bool pressed = ButtonBehaviour(bb, id, &hovered, &held, repeat_when_held);
bool pressed = ButtonBehaviour(bb, id, &hovered, &held, true, repeat_when_held);
// Render
const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
@ -2661,7 +2717,7 @@ bool SmallButton(const char* label)
return false;
bool hovered, held;
bool pressed = ButtonBehaviour(bb, id, &hovered, &held);
bool pressed = ButtonBehaviour(bb, id, &hovered, &held, true);
// Render
const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
@ -2681,7 +2737,7 @@ static bool CloseWindowButton(bool* open)
const ImGuiAabb bb(window->Aabb().GetTR() + ImVec2(-title_bar_height+3.0f,2.0f), window->Aabb().GetTR() + ImVec2(-2.0f,+title_bar_height-2.0f));
bool hovered, held;
bool pressed = ButtonBehaviour(bb, id, &hovered, &held);
bool pressed = ButtonBehaviour(bb, id, &hovered, &held, true);
// Render
const ImU32 col = window->Color((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_CloseButtonHovered : ImGuiCol_CloseButton);
@ -2818,7 +2874,7 @@ bool CollapsingHeader(const char* label, const char* str_id, const bool display_
return opened;
bool hovered, held;
bool pressed = ButtonBehaviour(display_frame ? bb : text_bb, id, &hovered, &held);
bool pressed = ButtonBehaviour(display_frame ? bb : text_bb, id, &hovered, &held, false);
if (pressed)
{
opened = !opened;
@ -3306,7 +3362,13 @@ enum ImGuiPlotType
ImGuiPlotType_Histogram,
};
static void Plot(ImGuiPlotType plot_type, const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size)
static float PlotGetValue(const float* values, size_t stride, int idx)
{
float v = *(float*)((unsigned char*)values + idx * stride);
return v;
}
static void Plot(ImGuiPlotType plot_type, const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, size_t stride)
{
ImGuiState& g = GImGui;
ImGuiWindow* window = GetCurrentWindow();
@ -3336,8 +3398,9 @@ static void Plot(ImGuiPlotType plot_type, const char* label, const float* values
float v_max = -FLT_MAX;
for (int i = 0; i < values_count; i++)
{
v_min = ImMin(v_min, values[i]);
v_max = ImMax(v_max, values[i]);
const float v = PlotGetValue(values, stride, i);
v_min = ImMin(v_min, v);
v_max = ImMax(v_max, v);
}
if (scale_min == FLT_MAX)
scale_min = v_min;
@ -3359,8 +3422,8 @@ static void Plot(ImGuiPlotType plot_type, const char* label, const float* values
const int v_idx = (int)(t * (values_count + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0)));
IM_ASSERT(v_idx >= 0 && v_idx < values_count);
const float v0 = values[(v_idx + values_offset) % values_count];
const float v1 = values[(v_idx + 1 + values_offset) % values_count];
const float v0 = PlotGetValue(values, stride, (v_idx + values_offset) % values_count);
const float v1 = PlotGetValue(values, stride, (v_idx + 1 + values_offset) % values_count);
if (plot_type == ImGuiPlotType_Lines)
ImGui::SetTooltip("%d: %8.4g\n%d: %8.4g", v_idx, v0, v_idx+1, v1);
else if (plot_type == ImGuiPlotType_Histogram)
@ -3370,19 +3433,19 @@ static void Plot(ImGuiPlotType plot_type, const char* label, const float* values
const float t_step = 1.0f / (float)res_w;
float v0 = values[(0 + values_offset) % values_count];
float v0 = PlotGetValue(values, stride, (0 + values_offset) % values_count);
float t0 = 0.0f;
ImVec2 p0 = ImVec2( t0, 1.0f - ImSaturate((v0 - scale_min) / (scale_max - scale_min)) );
const ImU32 col_base = window->Color((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLines : ImGuiCol_PlotHistogram);
const ImU32 col_hovered = window->Color((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLinesHovered : ImGuiCol_PlotHistogramHovered);
while (t0 < 1.0f)
for (int n = 0; n < res_w; n++)
{
const float t1 = t0 + t_step;
const int v_idx = (int)(t0 * values_count);
IM_ASSERT(v_idx >= 0 && v_idx < values_count);
const float v1 = values[(v_idx + values_offset + 1) % values_count];
const float v1 = PlotGetValue(values, stride, (v_idx + values_offset + 1) % values_count);
const ImVec2 p1 = ImVec2( t1, 1.0f - ImSaturate((v1 - scale_min) / (scale_max - scale_min)) );
// NB: draw calls are merged into ones
@ -3403,14 +3466,14 @@ static void Plot(ImGuiPlotType plot_type, const char* label, const float* values
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, graph_bb.Min.y), label);
}
void PlotLines(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size)
void PlotLines(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, size_t stride)
{
ImGui::Plot(ImGuiPlotType_Lines, label, values, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size);
ImGui::Plot(ImGuiPlotType_Lines, label, values, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size, stride);
}
void PlotHistogram(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size)
void PlotHistogram(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, size_t stride)
{
ImGui::Plot(ImGuiPlotType_Histogram, label, values, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size);
ImGui::Plot(ImGuiPlotType_Histogram, label, values, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size, stride);
}
void Checkbox(const char* label, bool* v)
@ -4076,10 +4139,12 @@ bool Combo(const char* label, int* current_item, bool (*items_getter)(void*, int
if (ClipAdvance(frame_bb))
return false;
const bool hovered = (g.HoveredWindow == window) && (g.HoveredId == 0) && IsMouseHoveringBox(bb);
bool value_changed = false;
ItemSize(frame_bb);
RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg));
RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, window->Color(ImGuiCol_Button));
RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, window->Color(hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button));
RenderCollapseTriangle(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y) + style.FramePadding, true);
if (*current_item >= 0 && *current_item < items_count)
@ -4093,7 +4158,6 @@ bool Combo(const char* label, int* current_item, bool (*items_getter)(void*, int
ImGui::TextUnformatted(label, FindTextDisplayEnd(label));
ImGui::PushID(id);
const bool hovered = (g.HoveredWindow == window) && (g.HoveredId == 0) && IsMouseHoveringBox(bb);
bool menu_toggled = false;
if (hovered)
{
@ -4130,7 +4194,7 @@ bool Combo(const char* label, int* current_item, bool (*items_getter)(void*, int
const ImGuiID item_id = child_window->GetID((void*)(intptr_t)item_idx);
bool item_hovered, item_held;
bool item_pressed = ButtonBehaviour(item_aabb, item_id, &item_hovered, &item_held);
bool item_pressed = ButtonBehaviour(item_aabb, item_id, &item_hovered, &item_held, true);
bool item_selected = item_idx == *current_item;
if (item_hovered || item_selected)
@ -4448,7 +4512,7 @@ bool IsClipped(const ImGuiAabb& bb)
return false;
}
bool IsClipped(ImVec2 item_size)
bool IsClipped(const ImVec2& item_size)
{
ImGuiWindow* window = GetCurrentWindow();
return IsClipped(ImGuiAabb(window->DC.CursorPos, window->DC.CursorPos + item_size));
@ -4574,7 +4638,7 @@ void Columns(int columns_count, const char* id, bool border)
continue;
bool hovered, held;
ButtonBehaviour(column_aabb, column_id, &hovered, &held);
ButtonBehaviour(column_aabb, column_id, &hovered, &held, true);
// 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);
@ -5118,7 +5182,7 @@ ImVec2 ImBitmapFont::CalcTextSize(float size, float max_width, const char* text_
text_size.y += line_height;
line_width = 0;
}
if (const FntGlyph* glyph = FindGlyph((unsigned short)c))
else if (const FntGlyph* glyph = FindGlyph((unsigned short)c))
{
const float char_width = (glyph->XAdvance + Info->SpacingHoriz) * scale;
//const float char_extend = (glyph->XOffset + glyph->Width * scale);
@ -5278,7 +5342,7 @@ static void SetClipboardTextFn_DefaultImpl(const char* text, const char* text_en
return;
if (!text_end)
text_end = text + strlen(text);
const int buf_length = (text_end - text) + 1;
const int buf_length = (int)(text_end - text) + 1;
HGLOBAL buf_handle = GlobalAlloc(GMEM_MOVEABLE, buf_length * sizeof(char));
if (buf_handle == NULL)
return;
@ -5480,6 +5544,14 @@ void ShowTestWindow(bool* open)
ImGui::TreePop();
}
if (ImGui::TreeNode("Colored Text"))
{
// This is a merely a shortcut, you can use PushStyleColor()/PopStyleColor() for more flexibility.
ImGui::TextColored(ImVec4(1.0f,0.0f,1.0f,1.0f), "Pink");
ImGui::TextColored(ImVec4(1.0f,1.0f,0.0f,1.0f), "Yellow");
ImGui::TreePop();
}
static int e = 0;
ImGui::RadioButton("radio a", &e, 0); ImGui::SameLine();
ImGui::RadioButton("radio b", &e, 1); ImGui::SameLine();
@ -5489,6 +5561,17 @@ void ShowTestWindow(bool* open)
if (ImGui::IsHovered())
ImGui::SetTooltip("I am a tooltip");
ImGui::SameLine();
ImGui::Text("- or me");
if (ImGui::IsHovered())
{
ImGui::BeginTooltip();
ImGui::Text("I am a fancy tooltip");
static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr));
ImGui::EndTooltip();
}
static int item = 1;
ImGui::Combo("combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0");

35
imgui.h
View file

@ -155,7 +155,7 @@ namespace ImGui
bool GetWindowIsFocused();
float GetWindowWidth();
ImVec2 GetWindowPos(); // you should rarely need/care about the window position, but it can be useful if you want to use your own drawing
void SetWindowPos(ImVec2 pos); // unchecked
void SetWindowPos(const ImVec2& pos); // set current window pos
ImVec2 GetWindowSize();
ImVec2 GetWindowContentRegionMin();
ImVec2 GetWindowContentRegionMax();
@ -169,9 +169,14 @@ namespace ImGui
float GetItemWidth();
void PushAllowKeyboardFocus(bool v);
void PopAllowKeyboardFocus();
void PushStyleColor(ImGuiCol idx, ImVec4 col);
void PushStyleColor(ImGuiCol idx, const ImVec4& col);
void PopStyleColor();
// Tooltip
void SetTooltip(const char* fmt, ...); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins.
void BeginTooltip(); // use to create full-featured tooltip windows that aren't just text.
void EndTooltip();
// Layout
void Separator(); // horizontal line
void SameLine(int column_x = 0, int spacing_w = -1); // call between widgets to layout them horizontally
@ -181,8 +186,8 @@ 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 relative to window position
void SetCursorPos(ImVec2 p);
ImVec2 GetCursorPos(); // cursor position is relative to window position
void SetCursorPos(const ImVec2& pos); // "
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();
@ -196,6 +201,7 @@ namespace ImGui
// Widgets
void Text(const char* fmt, ...);
void TextV(const char* fmt, va_list args);
void TextColored(const ImVec4& col, const char* fmt, ...); // shortcut to doing PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor();
void TextUnformatted(const char* text, const char* text_end = NULL); // doesn't require null terminated string if 'text_end' is specified. no copy done to any bounded stack buffer, better for long chunks of text.
void LabelText(const char* label, const char* fmt, ...);
void BulletText(const char* fmt, ...);
@ -207,8 +213,8 @@ namespace ImGui
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");
void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0));
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));
void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float));
void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float));
void Checkbox(const char* label, bool* v);
void CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
bool RadioButton(const char* label, bool active);
@ -249,12 +255,11 @@ namespace ImGui
void LogToClipboard(int max_depth = -1);
// Utilities
void SetTooltip(const char* fmt, ...); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). (currently no contention handling, last call win)
void SetNewWindowDefaultPos(ImVec2 pos); // set position of window that do
void SetNewWindowDefaultPos(const ImVec2& pos); // set position of window that do
bool IsHovered(); // was the last item active area hovered by mouse?
ImVec2 GetItemBoxMin(); // get bounding box of last item
ImVec2 GetItemBoxMax(); // get bounding box of last item
bool IsClipped(ImVec2 item_size); // to perform coarse clipping on user's side (as an optimisation)
bool IsClipped(const ImVec2& item_size); // to perform coarse clipping on user's side (as an optimisation)
bool IsKeyPressed(int key_index, bool repeat = true); // key_index into the keys_down[512] array, imgui doesn't know the semantic of each entry
bool IsMouseClicked(int button, bool repeat = false);
bool IsMouseDoubleClicked(int button);
@ -419,7 +424,7 @@ struct ImGuiIO
// Input - Fill before calling NewFrame()
ImVec2 MousePos; // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
bool MouseDown[2]; // Mouse buttons
bool MouseDown[5]; // Mouse buttons. ImGui itself only uses button 0 (left button) but you can use others as storage for convenience.
int MouseWheel; // Mouse wheel: -1,0,+1
bool KeyCtrl; // Keyboard modifier pressed: Control
bool KeyShift; // Keyboard modifier pressed: Shift
@ -436,11 +441,11 @@ struct ImGuiIO
// [Internal] ImGui will maintain those fields for you
ImVec2 MousePosPrev;
ImVec2 MouseDelta;
bool MouseClicked[2];
ImVec2 MouseClickedPos[2];
float MouseClickedTime[2];
bool MouseDoubleClicked[2];
float MouseDownTime[2];
bool MouseClicked[5];
ImVec2 MouseClickedPos[5];
float MouseClickedTime[5];
bool MouseDoubleClicked[5];
float MouseDownTime[5];
float KeysDownTime[512];
ImGuiIO();