Merge branch 'master' into docking

# Conflicts:
#	docs/CHANGELOG.txt
#	imgui_internal.h
This commit is contained in:
ocornut 2020-04-20 11:33:56 +02:00
commit 266dff9bed
11 changed files with 169 additions and 42 deletions

View File

@ -99,10 +99,28 @@ Other changes:
to make the examples main.cpp easier to read. to make the examples main.cpp easier to read.
-----------------------------------------------------------------------
VERSION 1.77 WIP (In Progress)
-----------------------------------------------------------------------
Breaking Changes:
Other Changes:
- TreeNode: Fixed bug where BeginDragDropSource() failed when the _OpenOnDoubleClick flag is
enabled (bug introduced in 1.76, but pre-1.76 it would also fail unless the _OpenOnArrow
flag was also set, and _OpenOnArrow is frequently set along with _OpenOnDoubleClick).
- TreeNode: Fixed bug where dragging a payload over a TreeNode() with either _OpenOnDoubleClick
or _OpenOnArrow would open the node. (#143)
- Backends: Win32: Support for #define NOGDI, won't try to call GetDeviceCaps(). (#3137, #2327)
----------------------------------------------------------------------- -----------------------------------------------------------------------
VERSION 1.76 (Released 2020-04-12) VERSION 1.76 (Released 2020-04-12)
----------------------------------------------------------------------- -----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.76
Other Changes: Other Changes:
- Drag and Drop, Nav: Disabling navigation arrow keys when drag and drop is active. In the docking - Drag and Drop, Nav: Disabling navigation arrow keys when drag and drop is active. In the docking

View File

@ -168,7 +168,7 @@ Unique ID are implicitly built from the hash of multiple elements that identify
- Unique ID are often derived from a string label and at minimum scoped within their host window: - Unique ID are often derived from a string label and at minimum scoped within their host window:
```c ```c
Begin("MyWindow"); Begin("MyWindow");
Button("OK"); // Label = "OK", ID = hash of ("MyWindow" "OK") Button("OK"); // Label = "OK", ID = hash of ("MyWindow", "OK")
Button("Cancel"); // Label = "Cancel", ID = hash of ("MyWindow", "Cancel") Button("Cancel"); // Label = "Cancel", ID = hash of ("MyWindow", "Cancel")
End(); End();
``` ```

View File

@ -97,7 +97,7 @@ Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcas
![screenshot demo](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png) ![screenshot demo](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png)
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here: You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here:
- [imgui-demo-binaries-20190715.zip](http://www.dearimgui.org/binaries/imgui-demo-binaries-20200412.zip) (Windows binaries, 1.76 WIP, built 2020/04/12, master branch, 5 executables) or [older demo binaries](http://www.dearimgui.org/binaries). - [imgui-demo-binaries-20190715.zip](http://www.dearimgui.org/binaries/imgui-demo-binaries-20200412.zip) (Windows binaries, 1.76, built 2020/04/12, master branch) or [older demo binaries](http://www.dearimgui.org/binaries).
The demo applications are not DPI aware so expect some blurriness on a 4K screen. For DPI awareness in your application, you can load/reload your font at different scale, and scale your style with `style.ScaleAllSizes()`. The demo applications are not DPI aware so expect some blurriness on a 4K screen. For DPI awareness in your application, you can load/reload your font at different scale, and scale your style with `style.ScaleAllSizes()`.
@ -114,7 +114,7 @@ Officially maintained bindings (in repository):
Third-party bindings (see [Bindings](https://github.com/ocornut/imgui/wiki/Bindings/) page): Third-party bindings (see [Bindings](https://github.com/ocornut/imgui/wiki/Bindings/) page):
- Languages: C, C#/.Net, ChaiScript, D, Go, Haskell, Haxe/hxcpp, Java, JavaScript, Julia, Kotlin, Lua, Odin, Pascal, PureBasic, Python, Ruby, Rust, Swift... - Languages: C, C#/.Net, ChaiScript, D, Go, Haskell, Haxe/hxcpp, Java, JavaScript, Julia, Kotlin, Lua, Odin, Pascal, PureBasic, Python, Ruby, Rust, Swift...
- Frameworks: AGS/Adventure Game Studio, Amethyst, bsf, Cinder, Cocos2d-x, Diligent Engine, Flexium, GML/Game Maker Studio2, GTK3+OpenGL3, Irrlicht Engine, LÖVE+LUA, Magnum, NanoRT, Nim Game Lib, Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, px_render, Qt/QtDirect3D, SFML, Sokol, Unreal Engine 4, vtk, Win32 GDI. - Frameworks: AGS/Adventure Game Studio, Amethyst, bsf, Cinder, Cocos2d-x, Diligent Engine, Flexium, GML/Game Maker Studio2, GTK3+OpenGL3, Irrlicht Engine, LÖVE+LUA, Magnum, NanoRT, Nim Game Lib, Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, Photoshop, px_render, Qt/QtDirect3D, SFML, Sokol, Unity, Unreal Engine 4, vtk, Win32 GDI, WxWidgets.
- Note that C bindings ([cimgui](https://github.com/cimgui/cimgui)) are auto-generated, you can use its json/lua output to generate bindings for other languages. - Note that C bindings ([cimgui](https://github.com/cimgui/cimgui)) are auto-generated, you can use its json/lua output to generate bindings for other languages.
Also see [Wiki](https://github.com/ocornut/imgui/wiki) for more links and ideas. Also see [Wiki](https://github.com/ocornut/imgui/wiki) for more links and ideas.

View File

@ -1,5 +1,5 @@
----------------------------------------------------------------------- -----------------------------------------------------------------------
dear imgui, v1.76 dear imgui, v1.77 WIP
----------------------------------------------------------------------- -----------------------------------------------------------------------
examples/README.txt examples/README.txt
(This is the README file for the examples/ folder. See docs/ for more documentation) (This is the README file for the examples/ folder. See docs/ for more documentation)

View File

@ -494,7 +494,7 @@ void ImGui_ImplWin32_EnableDpiAwareness()
SetProcessDPIAware(); SetProcessDPIAware();
} }
#ifdef _MSC_VER #if defined(_MSC_VER) && !defined(NOGDI)
#pragma comment(lib, "gdi32") // Link with gdi32.lib for GetDeviceCaps() #pragma comment(lib, "gdi32") // Link with gdi32.lib for GetDeviceCaps()
#endif #endif
@ -507,6 +507,7 @@ float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor)
if (PFN_GetDpiForMonitor GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor")) if (PFN_GetDpiForMonitor GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor"))
GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi); GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
} }
#ifndef NOGDI
else else
{ {
const HDC dc = ::GetDC(NULL); const HDC dc = ::GetDC(NULL);
@ -514,6 +515,7 @@ float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor)
ydpi = ::GetDeviceCaps(dc, LOGPIXELSY); ydpi = ::GetDeviceCaps(dc, LOGPIXELSY);
::ReleaseDC(NULL, dc); ::ReleaseDC(NULL, dc);
} }
#endif
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert! IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
return xdpi / 96.0f; return xdpi / 96.0f;
} }

View File

@ -1,4 +1,4 @@
// dear imgui, v1.76 // dear imgui, v1.77 WIP
// (main code and documentation) // (main code and documentation)
// Help: // Help:
@ -2942,6 +2942,10 @@ ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end)
ImGuiID seed = IDStack.back(); ImGuiID seed = IDStack.back();
ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed); ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed);
ImGui::KeepAliveID(id); ImGui::KeepAliveID(id);
#ifdef IMGUI_ENABLE_TEST_ENGINE
ImGuiContext& g = *GImGui;
IMGUI_TEST_ENGINE_ID_INFO2(id, ImGuiDataType_String, str, str_end);
#endif
return id; return id;
} }
@ -2950,6 +2954,10 @@ ImGuiID ImGuiWindow::GetID(const void* ptr)
ImGuiID seed = IDStack.back(); ImGuiID seed = IDStack.back();
ImGuiID id = ImHashData(&ptr, sizeof(void*), seed); ImGuiID id = ImHashData(&ptr, sizeof(void*), seed);
ImGui::KeepAliveID(id); ImGui::KeepAliveID(id);
#ifdef IMGUI_ENABLE_TEST_ENGINE
ImGuiContext& g = *GImGui;
IMGUI_TEST_ENGINE_ID_INFO(id, ImGuiDataType_Pointer, ptr);
#endif
return id; return id;
} }
@ -2958,25 +2966,44 @@ ImGuiID ImGuiWindow::GetID(int n)
ImGuiID seed = IDStack.back(); ImGuiID seed = IDStack.back();
ImGuiID id = ImHashData(&n, sizeof(n), seed); ImGuiID id = ImHashData(&n, sizeof(n), seed);
ImGui::KeepAliveID(id); ImGui::KeepAliveID(id);
#ifdef IMGUI_ENABLE_TEST_ENGINE
ImGuiContext& g = *GImGui;
IMGUI_TEST_ENGINE_ID_INFO(id, ImGuiDataType_S32, (intptr_t)n);
#endif
return id; return id;
} }
ImGuiID ImGuiWindow::GetIDNoKeepAlive(const char* str, const char* str_end) ImGuiID ImGuiWindow::GetIDNoKeepAlive(const char* str, const char* str_end)
{ {
ImGuiID seed = IDStack.back(); ImGuiID seed = IDStack.back();
return ImHashStr(str, str_end ? (str_end - str) : 0, seed); ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed);
#ifdef IMGUI_ENABLE_TEST_ENGINE
ImGuiContext& g = *GImGui;
IMGUI_TEST_ENGINE_ID_INFO2(id, ImGuiDataType_String, str, str_end);
#endif
return id;
} }
ImGuiID ImGuiWindow::GetIDNoKeepAlive(const void* ptr) ImGuiID ImGuiWindow::GetIDNoKeepAlive(const void* ptr)
{ {
ImGuiID seed = IDStack.back(); ImGuiID seed = IDStack.back();
return ImHashData(&ptr, sizeof(void*), seed); ImGuiID id = ImHashData(&ptr, sizeof(void*), seed);
#ifdef IMGUI_ENABLE_TEST_ENGINE
ImGuiContext& g = *GImGui;
IMGUI_TEST_ENGINE_ID_INFO(id, ImGuiDataType_Pointer, ptr);
#endif
return id;
} }
ImGuiID ImGuiWindow::GetIDNoKeepAlive(int n) ImGuiID ImGuiWindow::GetIDNoKeepAlive(int n)
{ {
ImGuiID seed = IDStack.back(); ImGuiID seed = IDStack.back();
return ImHashData(&n, sizeof(n), seed); ImGuiID id = ImHashData(&n, sizeof(n), seed);
#ifdef IMGUI_ENABLE_TEST_ENGINE
ImGuiContext& g = *GImGui;
IMGUI_TEST_ENGINE_ID_INFO(id, ImGuiDataType_S32, (intptr_t)n);
#endif
return id;
} }
// This is only used in rare/specific situations to manufacture an ID out of nowhere. // This is only used in rare/specific situations to manufacture an ID out of nowhere.
@ -3976,6 +4003,7 @@ void ImGui::NewFrame()
g.DragDropAcceptIdCurrRectSurface = FLT_MAX; g.DragDropAcceptIdCurrRectSurface = FLT_MAX;
g.DragDropWithinSource = false; g.DragDropWithinSource = false;
g.DragDropWithinTarget = false; g.DragDropWithinTarget = false;
g.DragDropHoldJustPressedId = 0;
// Update keyboard input state // Update keyboard input state
// Synchronize io.KeyMods with individual modifiers io.KeyXXX bools // Synchronize io.KeyMods with individual modifiers io.KeyXXX bools
@ -5924,6 +5952,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
UpdateWindowParentAndRootLinks(window, flags, parent_window); UpdateWindowParentAndRootLinks(window, flags, parent_window);
// Process SetNextWindow***() calls // Process SetNextWindow***() calls
// (FIXME: Consider splitting the HasXXX flags into X/Y components
bool window_pos_set_by_api = false; bool window_pos_set_by_api = false;
bool window_size_x_set_by_api = false, window_size_y_set_by_api = false; bool window_size_x_set_by_api = false, window_size_y_set_by_api = false;
if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos)
@ -5948,6 +5977,19 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.y > 0.0f); window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.y > 0.0f);
SetWindowSize(window, g.NextWindowData.SizeVal, g.NextWindowData.SizeCond); SetWindowSize(window, g.NextWindowData.SizeVal, g.NextWindowData.SizeCond);
} }
if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasScroll)
{
if (g.NextWindowData.ScrollVal.x >= 0.0f)
{
window->ScrollTarget.x = g.NextWindowData.ScrollVal.x;
window->ScrollTargetCenterRatio.x = 0.0f;
}
if (g.NextWindowData.ScrollVal.y >= 0.0f)
{
window->ScrollTarget.y = g.NextWindowData.ScrollVal.y;
window->ScrollTargetCenterRatio.y = 0.0f;
}
}
if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasContentSize) if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasContentSize)
window->ContentSizeExplicit = g.NextWindowData.ContentSizeVal; window->ContentSizeExplicit = g.NextWindowData.ContentSizeVal;
else if (first_begin_of_the_frame) else if (first_begin_of_the_frame)
@ -7172,6 +7214,13 @@ void ImGui::SetNextWindowContentSize(const ImVec2& size)
g.NextWindowData.ContentSizeVal = size; g.NextWindowData.ContentSizeVal = size;
} }
void ImGui::SetNextWindowScroll(const ImVec2& scroll)
{
ImGuiContext& g = *GImGui;
g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasScroll;
g.NextWindowData.ScrollVal = scroll;
}
void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -7322,32 +7371,41 @@ ImGuiStorage* ImGui::GetStateStorage()
void ImGui::PushID(const char* str_id) void ImGui::PushID(const char* str_id)
{ {
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiContext& g = *GImGui;
window->IDStack.push_back(window->GetIDNoKeepAlive(str_id)); ImGuiWindow* window = g.CurrentWindow;
ImGuiID id = window->GetIDNoKeepAlive(str_id);
window->IDStack.push_back(id);
} }
void ImGui::PushID(const char* str_id_begin, const char* str_id_end) void ImGui::PushID(const char* str_id_begin, const char* str_id_end)
{ {
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiContext& g = *GImGui;
window->IDStack.push_back(window->GetIDNoKeepAlive(str_id_begin, str_id_end)); ImGuiWindow* window = g.CurrentWindow;
ImGuiID id = window->GetIDNoKeepAlive(str_id_begin, str_id_end);
window->IDStack.push_back(id);
} }
void ImGui::PushID(const void* ptr_id) void ImGui::PushID(const void* ptr_id)
{ {
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiContext& g = *GImGui;
window->IDStack.push_back(window->GetIDNoKeepAlive(ptr_id)); ImGuiWindow* window = g.CurrentWindow;
ImGuiID id = window->GetIDNoKeepAlive(ptr_id);
window->IDStack.push_back(id);
} }
void ImGui::PushID(int int_id) void ImGui::PushID(int int_id)
{ {
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiContext& g = *GImGui;
window->IDStack.push_back(window->GetIDNoKeepAlive(int_id)); ImGuiWindow* window = g.CurrentWindow;
ImGuiID id = window->GetIDNoKeepAlive(int_id);
window->IDStack.push_back(id);
} }
// Push a given id value ignoring the ID stack as a seed. // Push a given id value ignoring the ID stack as a seed.
void ImGui::PushOverrideID(ImGuiID id) void ImGui::PushOverrideID(ImGuiID id)
{ {
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
window->IDStack.push_back(id); window->IDStack.push_back(id);
} }

View File

@ -1,4 +1,4 @@
// dear imgui, v1.76 // dear imgui, v1.77 WIP
// (headers) // (headers)
// Help: // Help:
@ -60,8 +60,8 @@ Index of this file:
// Version // Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.76" #define IMGUI_VERSION "1.77 WIP"
#define IMGUI_VERSION_NUM 17600 #define IMGUI_VERSION_NUM 17601
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_VIEWPORT 1 // Viewport WIP branch #define IMGUI_HAS_VIEWPORT 1 // Viewport WIP branch
#define IMGUI_HAS_DOCK 1 // Docking WIP branch #define IMGUI_HAS_DOCK 1 // Docking WIP branch

View File

@ -1,4 +1,4 @@
// dear imgui, v1.76 // dear imgui, v1.77 WIP
// (demo code) // (demo code)
// Help: // Help:
@ -696,11 +696,13 @@ static void ShowDemoWindowWidgets()
HelpMarker("This is a more typical looking tree with selectable nodes.\nClick to select, CTRL+Click to toggle, click on arrows or double-click to open."); HelpMarker("This is a more typical looking tree with selectable nodes.\nClick to select, CTRL+Click to toggle, click on arrows or double-click to open.");
static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth; static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth;
static bool align_label_with_current_x_position = false; static bool align_label_with_current_x_position = false;
static bool test_drag_and_drop = false;
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_OpenOnArrow); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_OpenOnArrow);
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick);
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be layed out after the node."); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be layed out after the node.");
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanFullWidth); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanFullWidth);
ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position); ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position);
ImGui::Checkbox("Test tree node as drag source", &test_drag_and_drop);
ImGui::Text("Hello!"); ImGui::Text("Hello!");
if (align_label_with_current_x_position) if (align_label_with_current_x_position)
ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing()); ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing());
@ -720,6 +722,12 @@ static void ShowDemoWindowWidgets()
bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Node %d", i); bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Node %d", i);
if (ImGui::IsItemClicked()) if (ImGui::IsItemClicked())
node_clicked = i; node_clicked = i;
if (test_drag_and_drop && ImGui::BeginDragDropSource())
{
ImGui::SetDragDropPayload("_TREENODE", NULL, 0);
ImGui::Text("This is a drag and drop source");
ImGui::EndDragDropSource();
}
if (node_open) if (node_open)
{ {
ImGui::BulletText("Blah blah\nBlah Blah"); ImGui::BulletText("Blah blah\nBlah Blah");
@ -735,6 +743,12 @@ static void ShowDemoWindowWidgets()
ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Leaf %d", i); ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Leaf %d", i);
if (ImGui::IsItemClicked()) if (ImGui::IsItemClicked())
node_clicked = i; node_clicked = i;
if (test_drag_and_drop && ImGui::BeginDragDropSource())
{
ImGui::SetDragDropPayload("_TREENODE", NULL, 0);
ImGui::Text("This is a drag and drop source");
ImGui::EndDragDropSource();
}
} }
} }
if (node_clicked != -1) if (node_clicked != -1)

View File

@ -1,4 +1,4 @@
// dear imgui, v1.76 // dear imgui, v1.77 WIP
// (drawing and font code) // (drawing and font code)
/* /*

View File

@ -1,4 +1,4 @@
// dear imgui, v1.76 // dear imgui, v1.77 WIP
// (internal structures/api) // (internal structures/api)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@ -735,6 +735,14 @@ struct ImGuiDataTypeInfo
const char* ScanFmt; // Default scanf format for the type const char* ScanFmt; // Default scanf format for the type
}; };
// Extend ImGuiDataType_
enum ImGuiDataTypePrivate_
{
ImGuiDataType_String = ImGuiDataType_COUNT + 1,
ImGuiDataType_Pointer,
ImGuiDataType_ID
};
// Stacked color modifier, backup of modified data so we can restore it // Stacked color modifier, backup of modified data so we can restore it
struct ImGuiColorMod struct ImGuiColorMod
{ {
@ -997,9 +1005,10 @@ enum ImGuiNextWindowDataFlags_
ImGuiNextWindowDataFlags_HasSizeConstraint = 1 << 4, ImGuiNextWindowDataFlags_HasSizeConstraint = 1 << 4,
ImGuiNextWindowDataFlags_HasFocus = 1 << 5, ImGuiNextWindowDataFlags_HasFocus = 1 << 5,
ImGuiNextWindowDataFlags_HasBgAlpha = 1 << 6, ImGuiNextWindowDataFlags_HasBgAlpha = 1 << 6,
ImGuiNextWindowDataFlags_HasViewport = 1 << 7, ImGuiNextWindowDataFlags_HasScroll = 1 << 7,
ImGuiNextWindowDataFlags_HasDock = 1 << 8, ImGuiNextWindowDataFlags_HasViewport = 1 << 8,
ImGuiNextWindowDataFlags_HasWindowClass = 1 << 9 ImGuiNextWindowDataFlags_HasDock = 1 << 9,
ImGuiNextWindowDataFlags_HasWindowClass = 1 << 10
}; };
// Storage for SetNexWindow** functions // Storage for SetNexWindow** functions
@ -1014,6 +1023,7 @@ struct ImGuiNextWindowData
ImVec2 PosPivotVal; ImVec2 PosPivotVal;
ImVec2 SizeVal; ImVec2 SizeVal;
ImVec2 ContentSizeVal; ImVec2 ContentSizeVal;
ImVec2 ScrollVal;
bool PosUndock; bool PosUndock;
bool CollapsedVal; bool CollapsedVal;
ImRect SizeConstraintRect; ImRect SizeConstraintRect;
@ -1186,6 +1196,9 @@ struct ImGuiContext
bool WithinFrameScope; // Set by NewFrame(), cleared by EndFrame() bool WithinFrameScope; // Set by NewFrame(), cleared by EndFrame()
bool WithinFrameScopeWithImplicitWindow; // Set by NewFrame(), cleared by EndFrame() when the implicit debug window has been pushed bool WithinFrameScopeWithImplicitWindow; // Set by NewFrame(), cleared by EndFrame() when the implicit debug window has been pushed
bool WithinEndChild; // Set within EndChild() bool WithinEndChild; // Set within EndChild()
bool TestEngineHookItems; // Will call test engine hooks: ImGuiTestEngineHook_ItemAdd(), ImGuiTestEngineHook_ItemInfo(), ImGuiTestEngineHook_Log()
ImGuiID TestEngineHookIdInfo; // Will call test engine hooks: ImGuiTestEngineHook_IdInfo() from GetID()
void* TestEngine; // Test engine user data
// Windows state // Windows state
ImVector<ImGuiWindow*> Windows; // Windows, sorted in display order, back to front ImVector<ImGuiWindow*> Windows; // Windows, sorted in display order, back to front
@ -1325,6 +1338,7 @@ struct ImGuiContext
ImGuiID DragDropAcceptIdCurr; // Target item id (set at the time of accepting the payload) ImGuiID DragDropAcceptIdCurr; // Target item id (set at the time of accepting the payload)
ImGuiID DragDropAcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping drag and drop targets) ImGuiID DragDropAcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping drag and drop targets)
int DragDropAcceptFrameCount; // Last time a target expressed a desire to accept the source int DragDropAcceptFrameCount; // Last time a target expressed a desire to accept the source
ImGuiID DragDropHoldJustPressedId; // Set when holding a payload just made ButtonBehavior() return a press.
ImVector<unsigned char> DragDropPayloadBufHeap; // We don't expose the ImVector<> directly, ImGuiPayload only holds pointer+size ImVector<unsigned char> DragDropPayloadBufHeap; // We don't expose the ImVector<> directly, ImGuiPayload only holds pointer+size
unsigned char DragDropPayloadBufLocal[16]; // Local buffer for small payloads unsigned char DragDropPayloadBufLocal[16]; // Local buffer for small payloads
@ -1396,14 +1410,17 @@ struct ImGuiContext
{ {
Initialized = false; Initialized = false;
ConfigFlagsCurrFrame = ConfigFlagsLastFrame = ImGuiConfigFlags_None; ConfigFlagsCurrFrame = ConfigFlagsLastFrame = ImGuiConfigFlags_None;
FontAtlasOwnedByContext = shared_font_atlas ? false : true;
Font = NULL; Font = NULL;
FontSize = FontBaseSize = 0.0f; FontSize = FontBaseSize = 0.0f;
FontAtlasOwnedByContext = shared_font_atlas ? false : true;
IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)(); IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)();
Time = 0.0f; Time = 0.0f;
FrameCount = 0; FrameCount = 0;
FrameCountEnded = FrameCountPlatformEnded = FrameCountRendered = -1; FrameCountEnded = FrameCountPlatformEnded = FrameCountRendered = -1;
WithinFrameScope = WithinFrameScopeWithImplicitWindow = WithinEndChild = false; WithinFrameScope = WithinFrameScopeWithImplicitWindow = WithinEndChild = false;
TestEngineHookItems = false;
TestEngineHookIdInfo = 0;
TestEngine = NULL;
WindowsActiveCount = 0; WindowsActiveCount = 0;
CurrentWindow = NULL; CurrentWindow = NULL;
@ -1491,6 +1508,7 @@ struct ImGuiContext
DragDropAcceptIdCurrRectSurface = 0.0f; DragDropAcceptIdCurrRectSurface = 0.0f;
DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0; DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0;
DragDropAcceptFrameCount = -1; DragDropAcceptFrameCount = -1;
DragDropHoldJustPressedId = 0;
memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal)); memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal));
CurrentTabBar = NULL; CurrentTabBar = NULL;
@ -1909,6 +1927,7 @@ namespace ImGui
IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name); IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name);
// Scrolling // Scrolling
IMGUI_API void SetNextWindowScroll(const ImVec2& scroll); // Use -1.0f on one axis to leave as-is
IMGUI_API void SetScrollX(ImGuiWindow* window, float new_scroll_x); IMGUI_API void SetScrollX(ImGuiWindow* window, float new_scroll_x);
IMGUI_API void SetScrollY(ImGuiWindow* window, float new_scroll_y); IMGUI_API void SetScrollY(ImGuiWindow* window, float new_scroll_y);
IMGUI_API void SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio = 0.5f); IMGUI_API void SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio = 0.5f);
@ -2189,14 +2208,20 @@ extern void ImGuiTestEngineHook_PreNewFrame(ImGuiContext* ctx);
extern void ImGuiTestEngineHook_PostNewFrame(ImGuiContext* ctx); extern void ImGuiTestEngineHook_PostNewFrame(ImGuiContext* ctx);
extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ctx, const ImRect& bb, ImGuiID id); extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ctx, const ImRect& bb, ImGuiID id);
extern void ImGuiTestEngineHook_ItemInfo(ImGuiContext* ctx, ImGuiID id, const char* label, ImGuiItemStatusFlags flags); extern void ImGuiTestEngineHook_ItemInfo(ImGuiContext* ctx, ImGuiID id, const char* label, ImGuiItemStatusFlags flags);
extern void ImGuiTestEngineHook_IdInfo(ImGuiContext* ctx, ImGuiDataType data_type, ImGuiID id, const void* data_id);
extern void ImGuiTestEngineHook_IdInfo(ImGuiContext* ctx, ImGuiDataType data_type, ImGuiID id, const void* data_id, const void* data_id_end);
extern void ImGuiTestEngineHook_Log(ImGuiContext* ctx, const char* fmt, ...); extern void ImGuiTestEngineHook_Log(ImGuiContext* ctx, const char* fmt, ...);
#define IMGUI_TEST_ENGINE_ITEM_ADD(_BB, _ID) ImGuiTestEngineHook_ItemAdd(&g, _BB, _ID) // Register item bounding box #define IMGUI_TEST_ENGINE_ITEM_ADD(_BB,_ID) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemAdd(&g, _BB, _ID) // Register item bounding box
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS) ImGuiTestEngineHook_ItemInfo(&g, _ID, _LABEL, _FLAGS) // Register item label and status flags (optional) #define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemInfo(&g, _ID, _LABEL, _FLAGS) // Register item label and status flags (optional)
#define IMGUI_TEST_ENGINE_LOG(_FMT, ...) ImGuiTestEngineHook_Log(&g, _FMT, __VA_ARGS__) // Custom log entry from user land into test log #define IMGUI_TEST_ENGINE_LOG(_FMT,...) if (g.TestEngineHookItems) ImGuiTestEngineHook_Log(&g, _FMT, __VA_ARGS__) // Custom log entry from user land into test log
#define IMGUI_TEST_ENGINE_ID_INFO(_ID,_TYPE,_DATA) if (g.TestEngineHookIdInfo == id) ImGuiTestEngineHook_IdInfo(&g, _TYPE, _ID, (const void*)(_DATA));
#define IMGUI_TEST_ENGINE_ID_INFO2(_ID,_TYPE,_DATA,_DATA2) if (g.TestEngineHookIdInfo == id) ImGuiTestEngineHook_IdInfo(&g, _TYPE, _ID, (const void*)(_DATA), (const void*)(_DATA2));
#else #else
#define IMGUI_TEST_ENGINE_ITEM_ADD(_BB, _ID) do { } while (0) #define IMGUI_TEST_ENGINE_ITEM_ADD(_BB,_ID) do { } while (0)
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS) do { } while (0) #define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) do { } while (0)
#define IMGUI_TEST_ENGINE_LOG(_FMT, ...) do { } while (0) #define IMGUI_TEST_ENGINE_LOG(_FMT,...) do { } while (0)
#define IMGUI_TEST_ENGINE_ID_INFO(_ID,_TYPE,_DATA) do { } while (0)
#define IMGUI_TEST_ENGINE_ID_INFO2(_ID,_TYPE,_DATA,_DATA2) do { } while (0)
#endif #endif
#if defined(__clang__) #if defined(__clang__)

View File

@ -1,4 +1,4 @@
// dear imgui, v1.76 // dear imgui, v1.77 WIP
// (widgets code) // (widgets code)
/* /*
@ -486,7 +486,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
#ifdef IMGUI_ENABLE_TEST_ENGINE #ifdef IMGUI_ENABLE_TEST_ENGINE
if (id != 0 && window->DC.LastItemId != id) if (id != 0 && window->DC.LastItemId != id)
ImGuiTestEngineHook_ItemAdd(&g, bb, id); IMGUI_TEST_ENGINE_ITEM_ADD(bb, id);
#endif #endif
bool pressed = false; bool pressed = false;
@ -500,11 +500,13 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
if (g.DragDropActive && (flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers)) if (g.DragDropActive && (flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers))
if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem))
{ {
const float DRAG_DROP_HOLD_TIMER = 0.70f;
hovered = true; hovered = true;
SetHoveredID(id); SetHoveredID(id);
if (CalcTypematicRepeatAmount(g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, g.HoveredIdTimer + 0.0001f, 0.70f, 0.00f)) if (CalcTypematicRepeatAmount(g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, g.HoveredIdTimer + 0.0001f, DRAG_DROP_HOLD_TIMER, 0.00f))
{ {
pressed = true; pressed = true;
g.DragDropHoldJustPressedId = id;
FocusWindow(window); FocusWindow(window);
} }
} }
@ -1139,6 +1141,7 @@ bool ImGui::RadioButton(const char* label, bool active)
if (label_size.x > 0.0f) if (label_size.x > 0.0f)
RenderText(ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y), label); RenderText(ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y), label);
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags);
return pressed; return pressed;
} }
@ -5370,10 +5373,11 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
// It is rather standard that arrow click react on Down rather than Up and we'd be tempted to make it the default // It is rather standard that arrow click react on Down rather than Up and we'd be tempted to make it the default
// (by removing the _OpenOnArrow test below), however this would have a perhaps surprising effect on CollapsingHeader()? // (by removing the _OpenOnArrow test below), however this would have a perhaps surprising effect on CollapsingHeader()?
// So right now we are making this optional. May evolve later. // So right now we are making this optional. May evolve later.
// We set ImGuiButtonFlags_PressedOnClickRelease on OpenOnDoubleClick because we want the item to be active on the initial MouseDown in order for drag and drop to work.
if (is_mouse_x_over_arrow && (flags & ImGuiTreeNodeFlags_OpenOnArrow)) if (is_mouse_x_over_arrow && (flags & ImGuiTreeNodeFlags_OpenOnArrow))
button_flags |= ImGuiButtonFlags_PressedOnClick; button_flags |= ImGuiButtonFlags_PressedOnClick;
else if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) else if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick)
button_flags |= ImGuiButtonFlags_PressedOnDoubleClick; button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick;
else else
button_flags |= ImGuiButtonFlags_PressedOnClickRelease; button_flags |= ImGuiButtonFlags_PressedOnClickRelease;
@ -5385,7 +5389,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
bool toggled = false; bool toggled = false;
if (!is_leaf) if (!is_leaf)
{ {
if (pressed) if (pressed && g.DragDropHoldJustPressedId != id)
{ {
if ((flags & (ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick)) == 0 || (g.NavActivateId == id)) if ((flags & (ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick)) == 0 || (g.NavActivateId == id))
toggled = true; toggled = true;
@ -5393,8 +5397,12 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
toggled |= is_mouse_x_over_arrow && !g.NavDisableMouseHover; // Lightweight equivalent of IsMouseHoveringRect() since ButtonBehavior() already did the job toggled |= is_mouse_x_over_arrow && !g.NavDisableMouseHover; // Lightweight equivalent of IsMouseHoveringRect() since ButtonBehavior() already did the job
if ((flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) && g.IO.MouseDoubleClicked[0]) if ((flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) && g.IO.MouseDoubleClicked[0])
toggled = true; toggled = true;
if (g.DragDropActive && is_open) // When using Drag and Drop "hold to open" we keep the node highlighted after opening, but never close it again. }
toggled = false; else if (pressed && g.DragDropHoldJustPressedId == id)
{
IM_ASSERT(button_flags & ImGuiButtonFlags_PressedOnDragDropHold);
if (!is_open) // When using Drag and Drop "hold to open" we keep the node highlighted after opening, but never close it again.
toggled = true;
} }
if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Left && is_open) if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Left && is_open)
@ -5495,7 +5503,8 @@ void ImGui::TreePush(const void* ptr_id)
void ImGui::TreePushOverrideID(ImGuiID id) void ImGui::TreePushOverrideID(ImGuiID id)
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
Indent(); Indent();
window->DC.TreeDepth++; window->DC.TreeDepth++;
window->IDStack.push_back(id); window->IDStack.push_back(id);
@ -7098,6 +7107,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
const ImGuiID id = TabBarCalcTabID(tab_bar, label); 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 dummy 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) if (p_open && !*p_open)
{ {
PushItemFlag(ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus, true); PushItemFlag(ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus, true);