Updated ImGui.

This commit is contained in:
Бранимир Караџић
2020-08-04 21:04:33 -07:00
parent 1c044995bb
commit 4920ea4a6f
6 changed files with 219 additions and 149 deletions

View File

@@ -417,7 +417,7 @@ CODE
- 2019/04/29 (1.70) - removed GetContentRegionAvailWidth(), use GetContentRegionAvail().x instead. Kept inline redirection function (will obsolete).
- 2019/03/04 (1.69) - renamed GetOverlayDrawList() to GetForegroundDrawList(). Kept redirection function (will obsolete).
- 2019/02/26 (1.69) - renamed ImGuiColorEditFlags_RGB/ImGuiColorEditFlags_HSV/ImGuiColorEditFlags_HEX to ImGuiColorEditFlags_DisplayRGB/ImGuiColorEditFlags_DisplayHSV/ImGuiColorEditFlags_DisplayHex. Kept redirection enums (will obsolete).
- 2019/02/14 (1.68) - made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame). If for some reason your time step calculation gives you a zero value, replace it with a dummy small value!
- 2019/02/14 (1.68) - made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame). If for some reason your time step calculation gives you a zero value, replace it with an arbitrary small value!
- 2019/02/01 (1.68) - removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already).
- 2019/01/06 (1.67) - renamed io.InputCharacters[], marked internal as was always intended. Please don't access directly, and use AddInputCharacter() instead!
- 2019/01/06 (1.67) - renamed ImFontAtlas::GlyphRangesBuilder to ImFontGlyphRangesBuilder. Kept redirection typedef (will obsolete).
@@ -1665,8 +1665,8 @@ static inline int ImTextCharToUtf8(char* buf, int buf_size, unsigned int c)
// Not optimal but we very rarely use this function.
int ImTextCountUtf8BytesFromChar(const char* in_text, const char* in_text_end)
{
unsigned int dummy = 0;
return ImTextCharFromUtf8(&dummy, in_text, in_text_end);
unsigned int unused = 0;
return ImTextCharFromUtf8(&unused, in_text, in_text_end);
}
static inline int ImTextCountUtf8BytesFromChar(unsigned int c)
@@ -2162,7 +2162,7 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items
*out_items_display_end = end;
}
static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
static void SetCursorPosYAndSetupForPrevLine(float pos_y, float line_height)
{
// Set cursor position and a few other things so that SetScrollHereY() and Columns() can work when seeking cursor.
// FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue.
@@ -2194,7 +2194,7 @@ void ImGuiListClipper::Begin(int count, float items_height)
{
ImGui::CalcListClipping(ItemsCount, ItemsHeight, &DisplayStart, &DisplayEnd); // calculate how many to clip/display
if (DisplayStart > 0)
SetCursorPosYAndSetupDummyPrevLine(StartPosY + DisplayStart * ItemsHeight, ItemsHeight); // advance cursor
SetCursorPosYAndSetupForPrevLine(StartPosY + DisplayStart * ItemsHeight, ItemsHeight); // advance cursor
StepNo = 2;
}
}
@@ -2205,7 +2205,7 @@ void ImGuiListClipper::End()
return;
// In theory here we should assert that ImGui::GetCursorPosY() == StartPosY + DisplayEnd * ItemsHeight, but it feels saner to just seek at the end and not assert/crash the user.
if (ItemsCount < INT_MAX)
SetCursorPosYAndSetupDummyPrevLine(StartPosY + ItemsCount * ItemsHeight, ItemsHeight); // advance cursor
SetCursorPosYAndSetupForPrevLine(StartPosY + ItemsCount * ItemsHeight, ItemsHeight); // advance cursor
ItemsCount = -1;
StepNo = 3;
}
@@ -2239,7 +2239,7 @@ bool ImGuiListClipper::Step()
StepNo = 3;
return true;
}
if (StepNo == 2) // Step 2: dummy step only required if an explicit items_height was passed to constructor or Begin() and user still call Step(). Does nothing and switch to Step 3.
if (StepNo == 2) // Step 2: empty step only required if an explicit items_height was passed to constructor or Begin() and user still call Step(). Does nothing and switch to Step 3.
{
IM_ASSERT(DisplayStart >= 0 && DisplayEnd >= 0);
StepNo = 3;
@@ -3042,7 +3042,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
if ((window->DC.ItemFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
return false;
// Special handling for the dummy item after Begin() which represent the title bar or tab.
// Special handling for calling after Begin() which represent the title bar or tab.
// When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect the case.
if (window->DC.LastItemId == window->MoveId && window->WriteAccessed)
return false;
@@ -3063,10 +3063,13 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
return false;
if (!IsMouseHoveringRect(bb.Min, bb.Max))
return false;
if (g.NavDisableMouseHover || !IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
if (g.NavDisableMouseHover)
return false;
if (window->DC.ItemFlags & ImGuiItemFlags_Disabled)
if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None) || (window->DC.ItemFlags & ImGuiItemFlags_Disabled))
{
g.HoveredIdDisabled = true;
return false;
}
// We exceptionally allow this function to be called with id==0 to allow using it for easy high-level
// hover test in widgets code. We could also decide to split this function is two.
@@ -3366,9 +3369,15 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
if (root_window != NULL && !is_closed_popup)
{
StartMouseMovingWindow(g.HoveredWindow);
// Cancel moving if clicked outside of title bar
if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(root_window->Flags & ImGuiWindowFlags_NoTitleBar))
if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
g.MovingWindow = NULL;
// Cancel moving if clicked over an item which was disabled or inhibited by popups
if (g.HoveredId == 0 && g.HoveredIdDisabled)
g.MovingWindow = NULL;
}
else if (root_window == NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL)
{
@@ -3725,6 +3734,7 @@ void ImGui::NewFrame()
g.HoveredIdPreviousFrame = g.HoveredId;
g.HoveredId = 0;
g.HoveredIdAllowOverlap = false;
g.HoveredIdDisabled = false;
// Update ActiveId data (clear reference to active widget if the widget isn't alive anymore)
if (g.ActiveIdIsAlive != g.ActiveId && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
@@ -4447,6 +4457,7 @@ bool ImGui::IsMouseDoubleClicked(ImGuiMouseButton button)
return g.IO.MouseDoubleClicked[button];
}
// Return if a mouse click/drag went past the given threshold. Valid to call during the MouseReleased frame.
// [Internal] This doesn't test if the button is pressed
bool ImGui::IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold)
{
@@ -4719,7 +4730,7 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
{
FocusWindow(child_window);
NavInitWindow(child_window, false);
SetActiveID(id + 1, child_window); // Steal ActiveId with a dummy id so that key-press won't activate child item
SetActiveID(id + 1, child_window); // Steal ActiveId with another arbitrary id so that key-press won't activate child item
g.ActiveIdSource = ImGuiInputSource_Nav;
}
return ret;
@@ -7840,6 +7851,7 @@ void ImGui::EndPopup()
g.WithinEndChild = false;
}
// Open a popup if mouse button is released over the item
bool ImGui::OpenPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flags)
{
ImGuiWindow* window = GImGui->CurrentWindow;

View File

@@ -153,6 +153,7 @@ typedef int ImDrawCornerFlags; // -> enum ImDrawCornerFlags_ // Flags: f
typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList
typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas build
typedef int ImGuiBackendFlags; // -> enum ImGuiBackendFlags_ // Flags: for io.BackendFlags
typedef int ImGuiButtonFlags; // -> enum ImGuiButtonFlags_ // Flags: for InvisibleButton()
typedef int ImGuiColorEditFlags; // -> enum ImGuiColorEditFlags_ // Flags: for ColorEdit4(), ColorPicker4() etc.
typedef int ImGuiConfigFlags; // -> enum ImGuiConfigFlags_ // Flags: for io.ConfigFlags
typedef int ImGuiComboFlags; // -> enum ImGuiComboFlags_ // Flags: for BeginCombo()
@@ -437,7 +438,7 @@ namespace ImGui
// - You may also use one of the many IsItemXXX functions (e.g. IsItemActive, IsItemHovered, etc.) to query widget state.
IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0, 0)); // button
IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed within text
IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); // button behavior without the visuals, frequently useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.)
IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size, ImGuiButtonFlags flags = 0); // flexible button behavior without the visuals, frequently useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.)
IMGUI_API bool ArrowButton(const char* str_id, ImGuiDir dir); // square button with an arrow shape
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0));
IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding
@@ -446,7 +447,7 @@ namespace ImGui
IMGUI_API bool RadioButton(const char* label, bool active); // use with e.g. if (RadioButton("one", my_value==1)) { my_value = 1; }
IMGUI_API bool RadioButton(const char* label, int* v, int v_button); // shortcut to handle the above pattern when value is an integer
IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-1, 0), const char* overlay = NULL);
IMGUI_API void Bullet(); // draw a small circle and keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses
IMGUI_API void Bullet(); // draw a small circle + keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses
// Widgets: Combo Box
// - The BeginCombo()/EndCombo() api allows you to manage your contents and selection state however you want it, by creating e.g. Selectable() items.
@@ -877,6 +878,7 @@ enum ImGuiTreeNodeFlags_
// small flags values as a mouse button index, so we encode the mouse button in the first few bits of the flags.
// It is therefore guaranteed to be legal to pass a mouse button index in ImGuiPopupFlags.
// - For the same reason, we exceptionally default the ImGuiPopupFlags argument of BeginPopupContextXXX functions to 1 instead of 0.
// - Multiple buttons currently cannot be combined/or-ed in those functions (we could allow it later).
enum ImGuiPopupFlags_
{
ImGuiPopupFlags_None = 0,
@@ -1221,6 +1223,19 @@ enum ImGuiStyleVar_
#endif
};
// Flags for InvisibleButton() [extended in imgui_internal.h]
enum ImGuiButtonFlags_
{
ImGuiButtonFlags_None = 0,
ImGuiButtonFlags_MouseButtonLeft = 1 << 0, // React on left mouse button (default)
ImGuiButtonFlags_MouseButtonRight = 1 << 1, // React on right mouse button
ImGuiButtonFlags_MouseButtonMiddle = 1 << 2, // React on center mouse button
// [Internal]
ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle,
ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft
};
// Flags for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton()
enum ImGuiColorEditFlags_
{
@@ -1315,16 +1330,16 @@ enum ImGuiCond_
// Helpers: Memory allocations macros
// IM_MALLOC(), IM_FREE(), IM_NEW(), IM_PLACEMENT_NEW(), IM_DELETE()
// We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax.
// Defining a custom placement new() with a dummy parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions.
// Defining a custom placement new() with a custom parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions.
//-----------------------------------------------------------------------------
struct ImNewDummy {};
inline void* operator new(size_t, ImNewDummy, void* ptr) { return ptr; }
inline void operator delete(void*, ImNewDummy, void*) {} // This is only required so we can use the symmetrical new()
struct ImNewWrapper {};
inline void* operator new(size_t, ImNewWrapper, void* ptr) { return ptr; }
inline void operator delete(void*, ImNewWrapper, void*) {} // This is only required so we can use the symmetrical new()
#define IM_ALLOC(_SIZE) ImGui::MemAlloc(_SIZE)
#define IM_FREE(_PTR) ImGui::MemFree(_PTR)
#define IM_PLACEMENT_NEW(_PTR) new(ImNewDummy(), _PTR)
#define IM_NEW(_TYPE) new(ImNewDummy(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE
#define IM_PLACEMENT_NEW(_PTR) new(ImNewWrapper(), _PTR)
#define IM_NEW(_TYPE) new(ImNewWrapper(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE
template<typename T> void IM_DELETE(T* p) { if (p) { p->~T(); ImGui::MemFree(p); } }
//-----------------------------------------------------------------------------
@@ -1828,7 +1843,7 @@ struct ImGuiStorage
// ImGui::Text("line number %d", i);
// - Step 0: the clipper let you process the first element, regardless of it being visible or not, so we can measure the element height (step skipped if we passed a known height as second arg to constructor).
// - Step 1: the clipper infer height from first element, calculate the actual range of elements to display, and position the cursor before the first element.
// - (Step 2: dummy step only required if an explicit items_height was passed to constructor or Begin() and user call Step(). Does nothing and switch to Step 3.)
// - (Step 2: empty step only required if an explicit items_height was passed to constructor or Begin() and user call Step(). Does nothing and switch to Step 3.)
// - Step 3: the clipper validate that we have reached the expected Y position (corresponding to element DisplayEnd), advance the cursor to the end of the list and then returns 'false' to end the loop.
struct ImGuiListClipper
{

View File

@@ -1243,7 +1243,7 @@ static void ShowDemoWindowWidgets()
static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr));
// Create a dummy array of contiguous float values to plot
// Fill an array of contiguous float values to plot
// Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float
// and the sizeof() of your structure in the "stride" parameter.
static float values[90] = {};
@@ -1251,7 +1251,7 @@ static void ShowDemoWindowWidgets()
static double refresh_time = 0.0;
if (!animate || refresh_time == 0.0)
refresh_time = ImGui::GetTime();
while (refresh_time < ImGui::GetTime()) // Create dummy data at fixed 60 Hz rate for the demo
while (refresh_time < ImGui::GetTime()) // Create data at fixed 60 Hz rate for the demo
{
static float phase = 0.0f;
values[values_offset] = cosf(phase);
@@ -1351,7 +1351,7 @@ static void ShowDemoWindowWidgets()
ImGui::Text("Color button with Custom Picker Popup:");
// Generate a dummy default palette. The palette will persist and can be edited.
// Generate a default palette. The palette will persist and can be edited.
static bool saved_palette_init = true;
static ImVec4 saved_palette[32] = {};
if (saved_palette_init)
@@ -1932,8 +1932,8 @@ static void ShowDemoWindowWidgets()
if (embed_all_inside_a_child_window)
ImGui::EndChild();
static char dummy_str[] = "This is a dummy field to be able to tab-out of the widgets above.";
ImGui::InputText("dummy", dummy_str, IM_ARRAYSIZE(dummy_str), ImGuiInputTextFlags_ReadOnly);
static char unused_str[] = "This widget is only here to be able to tab-out of the widgets above.";
ImGui::InputText("unused", unused_str, IM_ARRAYSIZE(unused_str), ImGuiInputTextFlags_ReadOnly);
// Calling IsItemHovered() after begin returns the hovered status of the title bar.
// This is useful in particular if you want to create a context menu associated to the title bar of a window.
@@ -2376,7 +2376,7 @@ static void ShowDemoWindowLayout()
ImGui::SameLine(0.0f, spacing);
if (ImGui::TreeNode("Node##1"))
{
// Dummy tree data
// Placeholder tree data
for (int i = 0; i < 6; i++)
ImGui::BulletText("Item %d..", i);
ImGui::TreePop();
@@ -2392,7 +2392,7 @@ static void ShowDemoWindowLayout()
ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##2");
if (node_open)
{
// Dummy tree data
// Placeholder tree data
for (int i = 0; i < 6; i++)
ImGui::BulletText("Item %d..", i);
ImGui::TreePop();
@@ -2693,7 +2693,7 @@ static void ShowDemoWindowLayout()
ImGui::TextWrapped("(Click and drag)");
ImVec2 pos = ImGui::GetCursorScreenPos();
ImVec4 clip_rect(pos.x, pos.y, pos.x + size.x, pos.y + size.y);
ImGui::InvisibleButton("##dummy", size);
ImGui::InvisibleButton("##empty", size);
if (ImGui::IsItemActive() && ImGui::IsMouseDragging(0))
{
offset.x += ImGui::GetIO().MouseDelta.x;
@@ -2869,8 +2869,8 @@ static void ShowDemoWindowPopups()
ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n");
ImGui::Separator();
//static int dummy_i = 0;
//ImGui::Combo("Combo", &dummy_i, "Delete\0Delete harder\0");
//static int unused_i = 0;
//ImGui::Combo("Combo", &unused_i, "Delete\0Delete harder\0");
static bool dont_ask_me_next_time = false;
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
@@ -2892,7 +2892,7 @@ static void ShowDemoWindowPopups()
{
if (ImGui::BeginMenu("File"))
{
if (ImGui::MenuItem("Dummy menu item")) {}
if (ImGui::MenuItem("Some menu item")) {}
ImGui::EndMenu();
}
ImGui::EndMenuBar();
@@ -2911,8 +2911,8 @@ static void ShowDemoWindowPopups()
// Also demonstrate passing a bool* to BeginPopupModal(), this will create a regular close button which
// will close the popup. Note that the visibility state of popups is owned by imgui, so the input value
// of the bool actually doesn't matter here.
bool dummy_open = true;
if (ImGui::BeginPopupModal("Stacked 2", &dummy_open))
bool unused_open = true;
if (ImGui::BeginPopupModal("Stacked 2", &unused_open))
{
ImGui::Text("Hello from Stacked The Second!");
if (ImGui::Button("Close"))
@@ -3247,7 +3247,7 @@ static void ShowDemoWindowMisc()
if (ImGui::TreeNode("Tabbing"))
{
ImGui::Text("Use TAB/SHIFT+TAB to cycle through keyboard editable fields.");
static char buf[32] = "dummy";
static char buf[32] = "hello";
ImGui::InputText("1", buf, IM_ARRAYSIZE(buf));
ImGui::InputText("2", buf, IM_ARRAYSIZE(buf));
ImGui::InputText("3", buf, IM_ARRAYSIZE(buf));
@@ -3903,7 +3903,7 @@ static void ShowExampleAppMainMenuBar()
// (future version will add explicit flags to BeginMenu() to request processing shortcuts)
static void ShowExampleMenuFile()
{
ImGui::MenuItem("(dummy menu)", NULL, false, false);
ImGui::MenuItem("(demo menu)", NULL, false, false);
if (ImGui::MenuItem("New")) {}
if (ImGui::MenuItem("Open", "Ctrl+O")) {}
if (ImGui::BeginMenu("Open Recent"))
@@ -4067,8 +4067,8 @@ struct ExampleAppConsole
// 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();
if (ImGui::SmallButton("Add Debug Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine();
if (ImGui::SmallButton("Add Debug Error")) { AddLog("[error] something went wrong"); } ImGui::SameLine();
if (ImGui::SmallButton("Clear")) { ClearLog(); } ImGui::SameLine();
bool copy_to_clipboard = ImGui::SmallButton("Copy");
//static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); }
@@ -4558,7 +4558,7 @@ static void ShowExampleAppLayout(bool* p_open)
// [SECTION] Example App: Property Editor / ShowExampleAppPropertyEditor()
//-----------------------------------------------------------------------------
static void ShowDummyObject(const char* prefix, int uid)
static void ShowPlaceholderObject(const char* prefix, int uid)
{
// Use object uid as identifier. Most commonly you could also use the object pointer as a base ID.
ImGui::PushID(uid);
@@ -4570,13 +4570,13 @@ static void ShowDummyObject(const char* prefix, int uid)
ImGui::NextColumn();
if (node_open)
{
static float dummy_members[8] = { 0.0f, 0.0f, 1.0f, 3.1416f, 100.0f, 999.0f };
static float placeholder_members[8] = { 0.0f, 0.0f, 1.0f, 3.1416f, 100.0f, 999.0f };
for (int i = 0; i < 8; i++)
{
ImGui::PushID(i); // Use field index as identifier.
if (i < 2)
{
ShowDummyObject("Child", 424242);
ShowPlaceholderObject("Child", 424242);
}
else
{
@@ -4587,9 +4587,9 @@ static void ShowDummyObject(const char* prefix, int uid)
ImGui::NextColumn();
ImGui::SetNextItemWidth(-1);
if (i >= 5)
ImGui::InputFloat("##value", &dummy_members[i], 1.0f);
ImGui::InputFloat("##value", &placeholder_members[i], 1.0f);
else
ImGui::DragFloat("##value", &dummy_members[i], 0.01f);
ImGui::DragFloat("##value", &placeholder_members[i], 0.01f);
ImGui::NextColumn();
}
ImGui::PopID();
@@ -4619,9 +4619,9 @@ static void ShowExampleAppPropertyEditor(bool* p_open)
ImGui::Columns(2);
ImGui::Separator();
// Iterate dummy objects with dummy members (all the same data)
// Iterate placeholder objects (all the same data)
for (int obj_i = 0; obj_i < 3; obj_i++)
ShowDummyObject("Object", obj_i);
ShowPlaceholderObject("Object", obj_i);
ImGui::Columns(1);
ImGui::Separator();
@@ -4859,31 +4859,32 @@ static void ShowExampleAppCustomRendering(bool* p_open)
// overloaded operators, etc. Define IM_VEC2_CLASS_EXTRA in imconfig.h to create implicit conversions between your
// types and ImVec2/ImVec4. Dear ImGui defines overloaded operators but they are internal to imgui.cpp and not
// exposed outside (to avoid messing with your types) In this example we are not using the maths operators!
ImDrawList* draw_list = ImGui::GetWindowDrawList();
if (ImGui::BeginTabBar("##TabBar"))
{
if (ImGui::BeginTabItem("Primitives"))
{
ImGui::PushItemWidth(-ImGui::GetFontSize() * 10);
ImDrawList* draw_list = ImGui::GetWindowDrawList();
// Draw gradients
// (note that those are currently exacerbating our sRGB/Linear issues)
// Calling ImGui::GetColorU32() multiplies the given colors by the current Style Alpha, but you may pass the IM_COL32() directly as well..
ImGui::Text("Gradients");
ImVec2 gradient_size = ImVec2(ImGui::CalcItemWidth(), ImGui::GetFrameHeight());
{
ImVec2 p0 = ImGui::GetCursorScreenPos();
ImVec2 p1 = ImVec2(p0.x + gradient_size.x, p0.y + gradient_size.y);
ImU32 col_a = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
ImU32 col_b = ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
ImU32 col_a = ImGui::GetColorU32(IM_COL32(0, 0, 0, 255));
ImU32 col_b = ImGui::GetColorU32(IM_COL32(255, 255, 255, 255));
draw_list->AddRectFilledMultiColor(p0, p1, col_a, col_b, col_b, col_a);
ImGui::InvisibleButton("##gradient1", gradient_size);
}
{
ImVec2 p0 = ImGui::GetCursorScreenPos();
ImVec2 p1 = ImVec2(p0.x + gradient_size.x, p0.y + gradient_size.y);
ImU32 col_a = ImGui::GetColorU32(ImVec4(0.0f, 1.0f, 0.0f, 1.0f));
ImU32 col_b = ImGui::GetColorU32(ImVec4(1.0f, 0.0f, 0.0f, 1.0f));
ImU32 col_a = ImGui::GetColorU32(IM_COL32(0, 255, 0, 255));
ImU32 col_b = ImGui::GetColorU32(IM_COL32(255, 0, 0, 255));
draw_list->AddRectFilledMultiColor(p0, p1, col_a, col_b, col_b, col_a);
ImGui::InvisibleButton("##gradient2", gradient_size);
}
@@ -4904,6 +4905,7 @@ static void ShowExampleAppCustomRendering(bool* p_open)
if (ImGui::SliderInt("Circle segments", &circle_segments_override_v, 3, 40))
circle_segments_override = true;
ImGui::ColorEdit4("Color", &colf.x);
const ImVec2 p = ImGui::GetCursorScreenPos();
const ImU32 col = ImColor(colf);
const float spacing = 10.0f;
@@ -4911,94 +4913,137 @@ static void ShowExampleAppCustomRendering(bool* p_open)
const ImDrawCornerFlags corners_all = ImDrawCornerFlags_All;
const ImDrawCornerFlags corners_tl_br = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight;
const int circle_segments = circle_segments_override ? circle_segments_override_v : 0;
float x = p.x + 4.0f, y = p.y + 4.0f;
float x = p.x + 4.0f;
float y = p.y + 4.0f;
for (int n = 0; n < 2; n++)
{
// First line uses a thickness of 1.0f, second line uses the configurable thickness
float th = (n == 0) ? 1.0f : thickness;
draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // N-gon
draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th); x += sz + spacing; // Circle
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, corners_none, th); x += sz + spacing; // Square
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_all, th); x += sz + spacing; // Square with all rounded corners
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners
draw_list->AddTriangle(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col, th); x += sz + spacing; // Triangle
draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th); x += sz*0.4f + spacing; // Thin triangle
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!)
draw_list->AddLine(ImVec2(x, y), ImVec2(x, y + sz), col, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!)
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col, th); x += sz + spacing; // Diagonal line
draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // N-gon
draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th); x += sz + spacing; // Circle
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, corners_none, th); x += sz + spacing; // Square
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_all, th); x += sz + spacing; // Square with all rounded corners
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners
draw_list->AddTriangle(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col, th);x += sz + spacing; // Triangle
//draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th);x+= sz*0.4f + spacing; // Thin triangle
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!)
draw_list->AddLine(ImVec2(x, y), ImVec2(x, y + sz), col, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!)
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col, th); x += sz + spacing; // Diagonal line
draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x + sz*1.3f, y + sz*0.3f), ImVec2(x + sz - sz*1.3f, y + sz - sz*0.3f), ImVec2(x + sz, y + sz), col, th);
x = p.x + 4;
y += sz + spacing;
}
draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz*0.5f, col, ngon_sides); x += sz + spacing; // N-gon
draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments);x += sz + spacing; // Circle
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col); x += sz + spacing; // Square
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f); x += sz + spacing; // Square with all rounded corners
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br); x += sz + spacing; // Square with two rounded corners
draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col); x += sz + spacing; // Triangle
draw_list->AddTriangleFilled(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col); x += sz*0.4f + spacing; // Thin triangle
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + thickness), col); x += sz + spacing; // Horizontal line (faster than AddLine, but only handle integer thickness)
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + thickness, y + sz), col); x += spacing*2.0f; // Vertical line (faster than AddLine, but only handle integer thickness)
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col); x += sz; // Pixel (faster than AddLine)
draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz*0.5f, col, ngon_sides); x += sz + spacing; // N-gon
draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments); x += sz + spacing; // Circle
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col); x += sz + spacing; // Square
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f); x += sz + spacing; // Square with all rounded corners
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br); x += sz + spacing; // Square with two rounded corners
draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col); x += sz + spacing; // Triangle
//draw_list->AddTriangleFilled(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col); x += sz*0.4f + spacing; // Thin triangle
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + thickness), col); x += sz + spacing; // Horizontal line (faster than AddLine, but only handle integer thickness)
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + thickness, y + sz), col); x += spacing * 2.0f;// Vertical line (faster than AddLine, but only handle integer thickness)
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col); x += sz; // Pixel (faster than AddLine)
draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255));
ImGui::Dummy(ImVec2((sz + spacing) * 9.8f, (sz + spacing) * 3));
ImGui::Dummy(ImVec2((sz + spacing) * 8.8f, (sz + spacing) * 3.0f));
ImGui::PopItemWidth();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Canvas"))
{
static ImVector<ImVec2> points;
struct ItemLine { ImVec2 p0, p1; ItemLine(const ImVec2& _p0, const ImVec2& _p1) { p0 = _p0; p1 = _p1; } };
static ImVector<ItemLine> lines;
static ImVec2 scrolling(0.0f, 0.0f);
static bool opt_enable_grid = true;
static bool opt_enable_context_menu = true;
static bool adding_line = false;
if (ImGui::Button("Clear")) points.clear();
if (points.Size >= 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) { points.pop_back(); points.pop_back(); } }
ImGui::Text("Left-click and drag to add lines,\nRight-click to undo");
// Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use
// IsItemHovered(). But you can also draw directly and poll mouse/keyboard by yourself.
// You can manipulate the cursor using GetCursorPos() and SetCursorPos().
// If you only use the ImDrawList API, you can notify the owner window of its extends with SetCursorPos(max).
ImVec2 canvas_p = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates!
ImGui::Checkbox("Enable grid", &opt_enable_grid);
ImGui::Checkbox("Enable context menu", &opt_enable_context_menu);
ImGui::Text("Mouse Left: drag to add lines,\nMouse Right: drag to scroll, click for context menu.");
// Typically you would use a BeginChild()/EndChild() pair to benefit from a clipping region + own scrolling.
// Here we demonstrate that this can be replaced by simple offsetting + custom drawing + PushClipRect/PopClipRect() calls.
// To use a child window instead we could use, e.g:
// ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); // Disable padding
// ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(50, 50, 50, 255)); // Set a background color
// ImGui::BeginChild("canvas", ImVec2(0.0f, 0.0f), true, ImGuiWindowFlags_NoMove);
// ImGui::PopStyleColor();
// ImGui::PopStyleVar();
// [...]
// ImGui::EndChild();
// Using InvisibleButton() as a convenience 1) it will advance the layout cursor and 2) allows us to use IsItemHovered()/IsItemActive()
ImVec2 canvas_p0 = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates!
ImVec2 canvas_sz = ImGui::GetContentRegionAvail(); // Resize canvas to what's available
if (canvas_sz.x < 50.0f) canvas_sz.x = 50.0f;
if (canvas_sz.y < 50.0f) canvas_sz.y = 50.0f;
draw_list->AddRectFilledMultiColor(canvas_p, ImVec2(canvas_p.x + canvas_sz.x, canvas_p.y + canvas_sz.y), IM_COL32(50, 50, 50, 255), IM_COL32(50, 50, 60, 255), IM_COL32(60, 60, 70, 255), IM_COL32(50, 50, 60, 255));
draw_list->AddRect(canvas_p, ImVec2(canvas_p.x + canvas_sz.x, canvas_p.y + canvas_sz.y), IM_COL32(255, 255, 255, 255));
ImVec2 canvas_p1 = ImVec2(canvas_p0.x + canvas_sz.x, canvas_p0.y + canvas_sz.y);
bool adding_preview = false;
ImGui::InvisibleButton("canvas", canvas_sz);
ImVec2 mouse_pos_global = ImGui::GetIO().MousePos;
ImVec2 mouse_pos_canvas = ImVec2(mouse_pos_global.x - canvas_p.x, mouse_pos_global.y - canvas_p.y);
// Draw border and background color
ImGuiIO& io = ImGui::GetIO();
ImDrawList* draw_list = ImGui::GetWindowDrawList();
draw_list->AddRectFilled(canvas_p0, canvas_p1, IM_COL32(50, 50, 50, 255));
draw_list->AddRect(canvas_p0, canvas_p1, IM_COL32(255, 255, 255, 255));
// This will catch our interactions
ImGui::InvisibleButton("canvas", canvas_sz, ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight);
const bool is_hovered = ImGui::IsItemHovered(); // Hovered
const bool is_active = ImGui::IsItemActive(); // Held
const ImVec2 origin(canvas_p0.x + scrolling.x, canvas_p0.y + scrolling.y); // Lock scrolled origin
const ImVec2 mouse_pos_in_canvas(io.MousePos.x - origin.x, io.MousePos.y - origin.y);
// Add first and second point
if (is_hovered && !adding_line && ImGui::IsMouseClicked(ImGuiMouseButton_Left))
{
lines.push_back(ItemLine(mouse_pos_in_canvas, mouse_pos_in_canvas));
adding_line = true;
}
if (adding_line)
{
adding_preview = true;
points.push_back(mouse_pos_canvas);
if (!ImGui::IsMouseDown(0))
adding_line = adding_preview = false;
}
if (ImGui::IsItemHovered())
{
if (!adding_line && ImGui::IsMouseClicked(0))
{
points.push_back(mouse_pos_canvas);
adding_line = true;
}
if (ImGui::IsMouseClicked(1) && !points.empty())
{
adding_line = adding_preview = false;
points.pop_back();
points.pop_back();
}
lines.back().p1 = mouse_pos_in_canvas;
if (!ImGui::IsMouseDown(ImGuiMouseButton_Left))
adding_line = false;
}
// Draw all lines in the canvas (with a clipping rectangle so they don't stray out of it).
draw_list->PushClipRect(canvas_p, ImVec2(canvas_p.x + canvas_sz.x, canvas_p.y + canvas_sz.y), true);
for (int i = 0; i < points.Size - 1; i += 2)
draw_list->AddLine(ImVec2(canvas_p.x + points[i].x, canvas_p.y + points[i].y), ImVec2(canvas_p.x + points[i + 1].x, canvas_p.y + points[i + 1].y), IM_COL32(255, 255, 0, 255), 2.0f);
// Pan (we use a zero mouse threshold when there's no context menu)
// You may decide to make that threshold dynamic based on whether the mouse is hovering something etc.
const float mouse_threshold_for_pan = opt_enable_context_menu ? -1.0f : 0.0f;
if (is_active && ImGui::IsMouseDragging(ImGuiMouseButton_Right, mouse_threshold_for_pan))
{
scrolling.x += io.MouseDelta.x;
scrolling.y += io.MouseDelta.y;
}
// Context menu (under default mouse threshold)
ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right);
if (opt_enable_context_menu && ImGui::IsMouseReleased(ImGuiMouseButton_Right) && drag_delta.x == 0.0f && drag_delta.y == 0.0f)
ImGui::OpenPopupContextItem("context");
if (ImGui::BeginPopup("context"))
{
if (adding_line)
lines.pop_back();
adding_line = false;
if (ImGui::MenuItem("Remove one", NULL, false, lines.Size > 0)) { lines.pop_back(); }
if (ImGui::MenuItem("Remove all", NULL, false, lines.Size > 0)) { lines.clear(); }
ImGui::EndPopup();
}
// Draw grid + all lines in the canvas
draw_list->PushClipRect(canvas_p0, canvas_p1, true);
if (opt_enable_grid)
{
const float GRID_STEP = 64.0f;
for (float x = fmodf(scrolling.x, GRID_STEP); x < canvas_sz.x; x += GRID_STEP)
draw_list->AddLine(ImVec2(canvas_p0.x + x, canvas_p0.y), ImVec2(canvas_p0.x + x, canvas_p1.y), IM_COL32(200, 200, 200, 40));
for (float y = fmodf(scrolling.y, GRID_STEP); y < canvas_sz.y; y += GRID_STEP)
draw_list->AddLine(ImVec2(canvas_p0.x, canvas_p0.y + y), ImVec2(canvas_p1.x, canvas_p0.y + y), IM_COL32(200, 200, 200, 40));
}
for (int n = 0; n < lines.Size; n++)
draw_list->AddLine(ImVec2(origin.x + lines[n].p0.x, origin.y + lines[n].p0.y), ImVec2(origin.x + lines[n].p1.x, origin.y + lines[n].p1.y), IM_COL32(255, 255, 0, 255), 2.0f);
draw_list->PopClipRect();
if (adding_preview)
points.pop_back();
ImGui::EndTabItem();
}
@@ -5053,7 +5098,7 @@ struct MyDocument
void DoForceClose() { Open = false; Dirty = false; }
void DoSave() { Dirty = false; }
// Display dummy contents for the Document
// Display placeholder contents for the Document
static void DisplayContents(MyDocument* doc)
{
ImGui::PushID(doc);

View File

@@ -2307,8 +2307,8 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
const int codepoint = src_tmp.GlyphsList[glyph_i];
const stbtt_packedchar& pc = src_tmp.PackedChars[glyph_i];
stbtt_aligned_quad q;
float dummy_x = 0.0f, dummy_y = 0.0f;
stbtt_GetPackedQuad(src_tmp.PackedChars, atlas->TexWidth, atlas->TexHeight, glyph_i, &dummy_x, &dummy_y, &q, 0);
float unused_x = 0.0f, unused_y = 0.0f;
stbtt_GetPackedQuad(src_tmp.PackedChars, atlas->TexWidth, atlas->TexHeight, glyph_i, &unused_x, &unused_y, &q, 0);
dst_font->AddGlyph(&cfg, (ImWchar)codepoint, q.x0 + font_off_x, q.y0 + font_off_y, q.x1 + font_off_x, q.y1 + font_off_y, q.s0, q.t0, q.s1, q.t1, pc.xadvance);
}
}

View File

@@ -604,32 +604,25 @@ enum ImGuiItemStatusFlags_
#endif
};
enum ImGuiButtonFlags_
// Extend ImGuiButtonFlags_
enum ImGuiButtonFlagsPrivate_
{
ImGuiButtonFlags_None = 0,
ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat
ImGuiButtonFlags_PressedOnClick = 1 << 1, // return true on click (mouse down event)
ImGuiButtonFlags_PressedOnClickRelease = 1 << 2, // [Default] return true on click + release on same item <-- this is what the majority of Button are using
ImGuiButtonFlags_PressedOnClickReleaseAnywhere = 1 << 3, // return true on click + release even if the release event is not done while hovering the item
ImGuiButtonFlags_PressedOnRelease = 1 << 4, // return true on release (default requires click+release)
ImGuiButtonFlags_PressedOnDoubleClick = 1 << 5, // return true on double-click (default requires click+release)
ImGuiButtonFlags_PressedOnDragDropHold = 1 << 6, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers)
ImGuiButtonFlags_FlattenChildren = 1 << 7, // allow interactions even if a child window is overlapping
ImGuiButtonFlags_AllowItemOverlap = 1 << 8, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap()
ImGuiButtonFlags_DontClosePopups = 1 << 9, // disable automatically closing parent popup on press // [UNUSED]
ImGuiButtonFlags_Disabled = 1 << 10, // disable interactions
ImGuiButtonFlags_AlignTextBaseLine = 1 << 11, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine
ImGuiButtonFlags_NoKeyModifiers = 1 << 12, // disable mouse interaction if a key modifier is held
ImGuiButtonFlags_NoHoldingActiveId = 1 << 13, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only)
ImGuiButtonFlags_NoNavFocus = 1 << 14, // don't override navigation focus when activated
ImGuiButtonFlags_NoHoveredOnFocus = 1 << 15, // don't report as hovered when nav focus is on this item
ImGuiButtonFlags_MouseButtonLeft = 1 << 16, // [Default] react on left mouse button
ImGuiButtonFlags_MouseButtonRight = 1 << 17, // react on right mouse button
ImGuiButtonFlags_MouseButtonMiddle = 1 << 18, // react on center mouse button
ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle,
ImGuiButtonFlags_MouseButtonShift_ = 16,
ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft,
ImGuiButtonFlags_PressedOnClick = 1 << 4, // return true on click (mouse down event)
ImGuiButtonFlags_PressedOnClickRelease = 1 << 5, // [Default] return true on click + release on same item <-- this is what the majority of Button are using
ImGuiButtonFlags_PressedOnClickReleaseAnywhere = 1 << 6, // return true on click + release even if the release event is not done while hovering the item
ImGuiButtonFlags_PressedOnRelease = 1 << 7, // return true on release (default requires click+release)
ImGuiButtonFlags_PressedOnDoubleClick = 1 << 8, // return true on double-click (default requires click+release)
ImGuiButtonFlags_PressedOnDragDropHold = 1 << 9, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers)
ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat
ImGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping
ImGuiButtonFlags_AllowItemOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap()
ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press // [UNUSED]
ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions
ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine
ImGuiButtonFlags_NoKeyModifiers = 1 << 16, // disable mouse interaction if a key modifier is held
ImGuiButtonFlags_NoHoldingActiveId = 1 << 17, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only)
ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated
ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item
ImGuiButtonFlags_PressedOnMask_ = ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClickReleaseAnywhere | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_PressedOnDragDropHold,
ImGuiButtonFlags_PressedOnDefault_ = ImGuiButtonFlags_PressedOnClickRelease
};
@@ -1144,8 +1137,9 @@ struct ImGuiContext
// Item/widgets state and tracking information
ImGuiID HoveredId; // Hovered widget
bool HoveredIdAllowOverlap;
ImGuiID HoveredIdPreviousFrame;
bool HoveredIdAllowOverlap;
bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0.
float HoveredIdTimer; // Measure contiguous hovering time
float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active
ImGuiID ActiveId; // Active widget
@@ -1348,9 +1342,9 @@ struct ImGuiContext
WheelingWindow = NULL;
WheelingWindowTimer = 0.0f;
HoveredId = 0;
HoveredId = HoveredIdPreviousFrame = 0;
HoveredIdAllowOverlap = false;
HoveredIdPreviousFrame = 0;
HoveredIdDisabled = false;
HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f;
ActiveId = 0;
ActiveIdIsAlive = 0;

View File

@@ -595,6 +595,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
}
}
// Process while held
bool held = false;
if (g.ActiveId == id)
{
@@ -615,6 +616,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
bool release_anywhere = (flags & ImGuiButtonFlags_PressedOnClickReleaseAnywhere) != 0;
if ((release_in || release_anywhere) && !g.DragDropActive)
{
// Report as pressed when releasing the mouse (this is the most common path)
bool is_double_click_release = (flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDownWasDoubleClick[mouse_button];
bool is_repeating_already = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button] >= g.IO.KeyRepeatDelay; // Repeat mode trumps <on release>
if (!is_double_click_release && !is_repeating_already)
@@ -627,6 +629,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
}
else if (g.ActiveIdSource == ImGuiInputSource_Nav)
{
// When activated using Nav, we hold on the ActiveID until activation button is released
if (g.NavActivateDownId != id)
ClearActiveID();
}
@@ -682,7 +685,7 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
bool ImGui::Button(const char* label, const ImVec2& size_arg)
{
return ButtonEx(label, size_arg, 0);
return ButtonEx(label, size_arg, ImGuiButtonFlags_None);
}
// Small buttons fits within text without additional vertical spacing.
@@ -698,7 +701,7 @@ bool ImGui::SmallButton(const char* label)
// 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)
bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg, ImGuiButtonFlags flags)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
@@ -715,7 +718,7 @@ bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg)
return false;
bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held);
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
return pressed;
}
@@ -5217,9 +5220,9 @@ void ImGui::ColorPickerOptionsPopup(const float* ref_col, ImGuiColorEditFlags fl
if (Selectable("##selectable", false, 0, picker_size)) // By default, Selectable() is closing popup
g.ColorEditOptions = (g.ColorEditOptions & ~ImGuiColorEditFlags__PickerMask) | (picker_flags & ImGuiColorEditFlags__PickerMask);
SetCursorScreenPos(backup_pos);
ImVec4 dummy_ref_col;
memcpy(&dummy_ref_col, ref_col, sizeof(float) * ((picker_flags & ImGuiColorEditFlags_NoAlpha) ? 3 : 4));
ColorPicker4("##dummypicker", &dummy_ref_col.x, picker_flags);
ImVec4 previewing_ref_col;
memcpy(&previewing_ref_col, ref_col, sizeof(float) * ((picker_flags & ImGuiColorEditFlags_NoAlpha) ? 3 : 4));
ColorPicker4("##previewing_picker", &previewing_ref_col.x, picker_flags);
PopID();
}
PopItemWidth();
@@ -5691,7 +5694,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags
// - Selectable()
//-------------------------------------------------------------------------
// Tip: pass a non-visible label (e.g. "##dummy") then you can use the space to draw other text or image.
// Tip: pass a non-visible label (e.g. "##hello") then you can use the space to draw other text or image.
// But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID or use ##unique_id.
// With this scheme, ImGuiSelectableFlags_SpanAllColumns and ImGuiSelectableFlags_AllowItemOverlap are also frequently used flags.
// FIXME: Selectable() with (size.x == 0.0f) and (SelectableTextAlign.x > 0.0f) followed by SameLine() is currently not supported.
@@ -7133,7 +7136,8 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
const ImGuiStyle& style = g.Style;
const ImGuiID id = TabBarCalcTabID(tab_bar, label);
// If the user called us with *p_open == false, we early out and don't render. We make a dummy call to ItemAdd() so that attempts to use a contextual popup menu with an implicit ID won't use an older ID.
// If the user called us with *p_open == false, we early out and don't render.
// We make a call to ItemAdd() so that attempts to use a contextual popup menu with an implicit ID won't use an older ID.
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
if (p_open && !*p_open)
{