|
@@ -77,7 +77,7 @@
|
|
|
- ESCAPE to revert text to its original value.
|
|
|
- You can apply arithmetic operators +,*,/ on numerical values. Use +- to subtract (because - would set a negative value!)
|
|
|
- Controls are automatically adjusted for OSX to match standard OSX text editing operations.
|
|
|
- - Gamepad navigation: see suggested mappings in imgui.h ImGuiNavInput_
|
|
|
+ - Gamepad navigation: see suggested mappings in imgui.h ImGuiNavInput_ + download PNG/PSD at goo.gl/9LgVZW.
|
|
|
|
|
|
|
|
|
PROGRAMMER GUIDE
|
|
@@ -229,6 +229,7 @@
|
|
|
0.0f= not held. 1.0f= fully held. Pass intermediate 0.0f..1.0f values for analog triggers/sticks.
|
|
|
- We uses a simple >0.0f test for activation testing, and won't attempt to test for a dead-zone.
|
|
|
Your code will probably need to transform your raw inputs (such as e.g. remapping your 0.2..0.9 raw input range to 0.0..1.0 imgui range, maybe a power curve, etc.).
|
|
|
+ - You can download PNG/PSD files depicting the gamepad controls for common controllers at: goo.gl/9LgVZW.
|
|
|
- If you need to share inputs between your game and the imgui parts, the easiest approach is to go all-or-nothing, with a buttons combo to toggle the target.
|
|
|
Please reach out if you think the game vs navigation input sharing could be improved.
|
|
|
- Mouse:
|
|
@@ -250,8 +251,9 @@
|
|
|
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.
|
|
|
Also read releases logs https://github.com/ocornut/imgui/releases for more details.
|
|
|
|
|
|
+ - 2018/03/03 (1.60) - Renamed ImGuiStyleVar_Count_ to ImGuiStyleVar_COUNT and ImGuiMouseCursor_Count_ to ImGuiMouseCursor_COUNT for consistency with other public enums.
|
|
|
- 2018/02/27 (1.XX) - removed io.DisplayVisibleMin, io.DisplayVisibleMax settings (it was used to clip within the DisplayPos..DisplayPos+Size range, I don't know of anyone using it)
|
|
|
- - 2018/02/18 (1.60) - BeginDragDropSource(): temporarily removed the optional mouse_button=0 parameter because it is not really usable in many situations at the moment.
|
|
|
+ - 2018/02/18 (1.60) - BeginDragDropSource(): temporarily removed the optional mouse_button=0 parameter because it is not really usable in many situations at the moment.
|
|
|
- 2018/02/16 (1.60) - obsoleted the io.RenderDrawListsFn callback, you can call your graphics engine render function after ImGui::Render(). Use ImGui::GetDrawData() to retrieve the ImDrawData* to display.
|
|
|
- 2018/02/07 (1.60) - reorganized context handling to be more explicit,
|
|
|
- YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END.
|
|
@@ -934,13 +936,6 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars)
|
|
|
#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose
|
|
|
#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
|
|
|
|
|
|
-// Play it nice with Windows users. Notepad in 2015 still doesn't display text data with Unix-style \n.
|
|
|
-#ifdef _WIN32
|
|
|
-#define IM_NEWLINE "\r\n"
|
|
|
-#else
|
|
|
-#define IM_NEWLINE "\n"
|
|
|
-#endif
|
|
|
-
|
|
|
ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p)
|
|
|
{
|
|
|
ImVec2 ap = p - a;
|
|
@@ -4729,7 +4724,7 @@ void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding)
|
|
|
}
|
|
|
|
|
|
// Render a triangle to denote expanded/collapsed state
|
|
|
-void ImGui::RenderTriangle(ImVec2 p_min, ImGuiDir dir, float scale)
|
|
|
+void ImGui::RenderArrow(ImVec2 p_min, ImGuiDir dir, float scale)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
ImGuiWindow* window = g.CurrentWindow;
|
|
@@ -4758,7 +4753,7 @@ void ImGui::RenderTriangle(ImVec2 p_min, ImGuiDir dir, float scale)
|
|
|
c = ImVec2(-0.500f,-0.866f) * r;
|
|
|
break;
|
|
|
case ImGuiDir_None:
|
|
|
- case ImGuiDir_Count_:
|
|
|
+ case ImGuiDir_COUNT:
|
|
|
IM_ASSERT(0);
|
|
|
break;
|
|
|
}
|
|
@@ -5657,8 +5652,8 @@ static ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window, const ImVec2& ref_p
|
|
|
// Combo Box policy (we want a connecting edge)
|
|
|
if (policy == ImGuiPopupPositionPolicy_ComboBox)
|
|
|
{
|
|
|
- const ImGuiDir dir_prefered_order[ImGuiDir_Count_] = { ImGuiDir_Down, ImGuiDir_Right, ImGuiDir_Left, ImGuiDir_Up };
|
|
|
- for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_Count_; n++)
|
|
|
+ const ImGuiDir dir_prefered_order[ImGuiDir_COUNT] = { ImGuiDir_Down, ImGuiDir_Right, ImGuiDir_Left, ImGuiDir_Up };
|
|
|
+ for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_COUNT; n++)
|
|
|
{
|
|
|
const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n];
|
|
|
if (n != -1 && dir == *last_dir) // Already tried this direction?
|
|
@@ -5676,8 +5671,8 @@ static ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window, const ImVec2& ref_p
|
|
|
}
|
|
|
|
|
|
// Default popup policy
|
|
|
- const ImGuiDir dir_prefered_order[ImGuiDir_Count_] = { ImGuiDir_Right, ImGuiDir_Down, ImGuiDir_Up, ImGuiDir_Left };
|
|
|
- for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_Count_; n++)
|
|
|
+ const ImGuiDir dir_prefered_order[ImGuiDir_COUNT] = { ImGuiDir_Right, ImGuiDir_Down, ImGuiDir_Up, ImGuiDir_Left };
|
|
|
+ for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_COUNT; n++)
|
|
|
{
|
|
|
const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n];
|
|
|
if (n != -1 && dir == *last_dir) // Already tried this direction?
|
|
@@ -6692,7 +6687,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
if (ButtonBehavior(bb, id, NULL, NULL))
|
|
|
window->CollapseToggleWanted = true; // Defer collapsing to next frame as we are too far in the Begin() function
|
|
|
RenderNavHighlight(bb, id);
|
|
|
- RenderTriangle(window->Pos + style.FramePadding, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f);
|
|
|
+ RenderArrow(window->Pos + style.FramePadding, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f);
|
|
|
}
|
|
|
|
|
|
// Close button
|
|
@@ -7210,8 +7205,8 @@ static const ImGuiStyleVarInfo GStyleVarInfo[] =
|
|
|
|
|
|
static const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx)
|
|
|
{
|
|
|
- IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_Count_);
|
|
|
- IM_ASSERT(IM_ARRAYSIZE(GStyleVarInfo) == ImGuiStyleVar_Count_);
|
|
|
+ IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_COUNT);
|
|
|
+ IM_ASSERT(IM_ARRAYSIZE(GStyleVarInfo) == ImGuiStyleVar_COUNT);
|
|
|
return &GStyleVarInfo[idx];
|
|
|
}
|
|
|
|
|
@@ -8283,6 +8278,32 @@ bool ImGui::SmallButton(const char* label)
|
|
|
return pressed;
|
|
|
}
|
|
|
|
|
|
+bool ImGui::ArrowButton(const char* str_id, ImGuiDir dir)
|
|
|
+{
|
|
|
+ ImGuiWindow* window = GetCurrentWindow();
|
|
|
+ if (window->SkipItems)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
+ const ImGuiID id = window->GetID(str_id);
|
|
|
+ float sz = ImGui::GetFrameHeight();
|
|
|
+ const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(sz, sz));
|
|
|
+ ItemSize(bb);
|
|
|
+ if (!ItemAdd(bb, id))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ bool hovered, held;
|
|
|
+ bool pressed = ButtonBehavior(bb, id, &hovered, &held);
|
|
|
+
|
|
|
+ // Render
|
|
|
+ const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
|
|
+ RenderNavHighlight(bb, id);
|
|
|
+ RenderFrame(bb.Min, bb.Max, col, true, g.Style.FrameRounding);
|
|
|
+ RenderArrow(bb.Min + g.Style.FramePadding, dir);
|
|
|
+
|
|
|
+ return pressed;
|
|
|
+}
|
|
|
+
|
|
|
// Tip: use ImGui::PushID()/PopID() to push indices or pointers in the ID stack.
|
|
|
// Then you can keep 'str_id' empty or the same for all your buttons (instead of creating a string based on a non-string id)
|
|
|
bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg)
|
|
@@ -8356,7 +8377,7 @@ bool ImGui::ArrowButton(ImGuiID id, ImGuiDir dir, ImVec2 padding, ImGuiButtonFla
|
|
|
const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
|
|
RenderNavHighlight(bb, id);
|
|
|
RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
|
|
|
- RenderTriangle(bb.Min + padding, dir, 1.0f);
|
|
|
+ RenderArrow(bb.Min + padding, dir, 1.0f);
|
|
|
|
|
|
return pressed;
|
|
|
}
|
|
@@ -8686,7 +8707,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|
|
// Framed type
|
|
|
RenderFrame(frame_bb.Min, frame_bb.Max, col, true, style.FrameRounding);
|
|
|
RenderNavHighlight(frame_bb, id, ImGuiNavHighlightFlags_TypeThin);
|
|
|
- RenderTriangle(frame_bb.Min + ImVec2(padding.x, text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f);
|
|
|
+ RenderArrow(frame_bb.Min + ImVec2(padding.x, text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f);
|
|
|
if (g.LogEnabled)
|
|
|
{
|
|
|
// NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here.
|
|
@@ -8713,7 +8734,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|
|
if (flags & ImGuiTreeNodeFlags_Bullet)
|
|
|
RenderBullet(frame_bb.Min + ImVec2(text_offset_x * 0.5f, g.FontSize*0.50f + text_base_offset_y));
|
|
|
else if (!(flags & ImGuiTreeNodeFlags_Leaf))
|
|
|
- RenderTriangle(frame_bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f);
|
|
|
+ RenderArrow(frame_bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f);
|
|
|
if (g.LogEnabled)
|
|
|
LogRenderedText(&text_pos, ">");
|
|
|
RenderText(text_pos, label, label_end, false);
|
|
@@ -9182,7 +9203,7 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v
|
|
|
const ImGuiStyle& style = g.Style;
|
|
|
|
|
|
// Draw frame
|
|
|
- const ImU32 frame_col = GetColorU32((g.ActiveId == id && g.ActiveIdSource == ImGuiInputSource_Nav) ? ImGuiCol_FrameBgActive : ImGuiCol_FrameBg);
|
|
|
+ const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
|
|
RenderNavHighlight(frame_bb, id);
|
|
|
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding);
|
|
|
|
|
@@ -11193,16 +11214,19 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
ImGuiCond backup_next_window_size_constraint = g.NextWindowData.SizeConstraintCond;
|
|
|
g.NextWindowData.SizeConstraintCond = 0;
|
|
|
-
|
|
|
+
|
|
|
ImGuiWindow* window = GetCurrentWindow();
|
|
|
if (window->SkipItems)
|
|
|
return false;
|
|
|
|
|
|
+ IM_ASSERT((flags & (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)) != (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)); // Can't use both flags together
|
|
|
+
|
|
|
const ImGuiStyle& style = g.Style;
|
|
|
const ImGuiID id = window->GetID(label);
|
|
|
- const float w = CalcItemWidth();
|
|
|
|
|
|
+ const float arrow_size = (flags & ImGuiComboFlags_NoArrowButton) ? 0.0f : GetFrameHeight();
|
|
|
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
|
+ const float w = (flags & ImGuiComboFlags_NoPreview) ? arrow_size : CalcItemWidth();
|
|
|
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f));
|
|
|
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
|
|
ItemSize(total_bb, style.FramePadding.y);
|
|
@@ -11213,13 +11237,18 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
|
|
bool pressed = ButtonBehavior(frame_bb, id, &hovered, &held);
|
|
|
bool popup_open = IsPopupOpen(id);
|
|
|
|
|
|
- const float arrow_size = GetFrameHeight();
|
|
|
const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f));
|
|
|
+ const ImU32 frame_col = GetColorU32(hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
|
|
RenderNavHighlight(frame_bb, id);
|
|
|
- RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
|
|
|
- RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING
|
|
|
- RenderTriangle(ImVec2(frame_bb.Max.x - arrow_size + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), ImGuiDir_Down);
|
|
|
- if (preview_value != NULL)
|
|
|
+ if (!(flags & ImGuiComboFlags_NoPreview))
|
|
|
+ window->DrawList->AddRectFilled(frame_bb.Min, ImVec2(frame_bb.Max.x - arrow_size, frame_bb.Max.y), frame_col, style.FrameRounding, ImDrawCornerFlags_Left);
|
|
|
+ if (!(flags & ImGuiComboFlags_NoArrowButton))
|
|
|
+ {
|
|
|
+ window->DrawList->AddRectFilled(ImVec2(frame_bb.Max.x - arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32((popup_open || hovered) ? ImGuiCol_ButtonHovered : ImGuiCol_Button), style.FrameRounding, (w <= arrow_size) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Right);
|
|
|
+ RenderArrow(ImVec2(frame_bb.Max.x - arrow_size + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), ImGuiDir_Down);
|
|
|
+ }
|
|
|
+ RenderFrameBorder(frame_bb.Min, frame_bb.Max, style.FrameRounding);
|
|
|
+ if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview))
|
|
|
RenderTextClipped(frame_bb.Min + style.FramePadding, value_bb.Max, preview_value, NULL, NULL, ImVec2(0.0f,0.0f));
|
|
|
if (label_size.x > 0)
|
|
|
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
|
@@ -11770,7 +11799,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
|
|
float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w);
|
|
|
pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
|
|
|
if (!enabled) PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
|
|
|
- RenderTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.30f, 0.0f), ImGuiDir_Right);
|
|
|
+ RenderArrow(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.30f, 0.0f), ImGuiDir_Right);
|
|
|
if (!enabled) PopStyleColor();
|
|
|
}
|
|
|
|
|
@@ -12346,7 +12375,7 @@ static void RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGui
|
|
|
case ImGuiDir_Right: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), pos, col); return;
|
|
|
case ImGuiDir_Up: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), pos, col); return;
|
|
|
case ImGuiDir_Down: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), pos, col); return;
|
|
|
- case ImGuiDir_None: case ImGuiDir_Count_: break; // Fix warnings
|
|
|
+ case ImGuiDir_None: case ImGuiDir_COUNT: break; // Fix warnings
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -13918,7 +13947,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
}
|
|
|
if (ImGui::TreeNode("Internal state"))
|
|
|
{
|
|
|
- const char* input_source_names[] = { "None", "Mouse", "Nav", "NavGamepad", "NavKeyboard" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_Count_);
|
|
|
+ const char* input_source_names[] = { "None", "Mouse", "Nav", "NavGamepad", "NavKeyboard" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT);
|
|
|
ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL");
|
|
|
ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL");
|
|
|
ImGui::Text("HoveredId: 0x%08X/0x%08X (%.2f sec)", g.HoveredId, g.HoveredIdPreviousFrame, g.HoveredIdTimer); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not
|