mirror of
https://github.com/wolfpld/tracy
synced 2025-04-30 12:53:51 +00:00
Bump ImGui to ~1.77.
This commit is contained in:
parent
7eb179b701
commit
4881f7aa54
396
imgui/imgui.cpp
396
imgui/imgui.cpp
@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.77 WIP
|
// dear imgui, v1.77
|
||||||
// (main code and documentation)
|
// (main code and documentation)
|
||||||
|
|
||||||
// Help:
|
// Help:
|
||||||
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
// Developed by Omar Cornut and every direct or indirect contributors to the GitHub.
|
// Developed by Omar Cornut and every direct or indirect contributors to the GitHub.
|
||||||
// See LICENSE.txt for copyright and licensing details (standard MIT License).
|
// See LICENSE.txt for copyright and licensing details (standard MIT License).
|
||||||
// This library is free but I need your support to sustain development and maintenance.
|
// This library is free but needs your support to sustain development and maintenance.
|
||||||
// Businesses: you can support continued development via invoiced technical support, maintenance and sponsoring contracts. Please reach out to "contact AT dearimgui.org".
|
// Businesses: you can support continued development via invoiced technical support, maintenance and sponsoring contracts. Please reach out to "contact AT dearimgui.org".
|
||||||
// Individuals: you can support continued development via donations. See docs/README or web page.
|
// Individuals: you can support continued development via donations. See docs/README or web page.
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ CODE
|
|||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
- Run and study the examples and demo in imgui_demo.cpp to get acquainted with the library.
|
- Run and study the examples and demo in imgui_demo.cpp to get acquainted with the library.
|
||||||
- In the majority of cases you should be able to use unmodified back-ends files available in the examples/ folder.
|
- In the majority of cases you should be able to use unmodified back-ends files available in the examples/ folder.
|
||||||
- Add the Dear ImGui source files to your projects or using your preferred build system.
|
- Add the Dear ImGui source files + selected back-end source files to your projects or using your preferred build system.
|
||||||
It is recommended you build and statically link the .cpp files as part of your project and NOT as shared library (DLL).
|
It is recommended you build and statically link the .cpp files as part of your project and NOT as shared library (DLL).
|
||||||
- You can later customize the imconfig.h file to tweak some compile-time behavior, such as integrating Dear ImGui types with your own maths types.
|
- You can later customize the imconfig.h file to tweak some compile-time behavior, such as integrating Dear ImGui types with your own maths types.
|
||||||
- When using Dear ImGui, your programming IDE is your friend: follow the declaration of variables, functions and types to find comments about them.
|
- When using Dear ImGui, your programming IDE is your friend: follow the declaration of variables, functions and types to find comments about them.
|
||||||
@ -375,15 +375,18 @@ CODE
|
|||||||
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
|
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
|
||||||
|
|
||||||
(Docking/Viewport Branch)
|
(Docking/Viewport Branch)
|
||||||
- 2019/XX/XX (1.XX) - when multi-viewports are enabled, all positions will be in your natural OS coordinates space. It means that:
|
- 2020/XX/XX (1.XX) - when multi-viewports are enabled, all positions will be in your natural OS coordinates space. It means that:
|
||||||
- reference to hard-coded positions such as in SetNextWindowPos(ImVec2(0,0)) are probably not what you want anymore.
|
- reference to hard-coded positions such as in SetNextWindowPos(ImVec2(0,0)) are probably not what you want anymore.
|
||||||
you may use GetMainViewport()->Pos to offset hard-coded positions, e.g. SetNextWindowPos(GetMainViewport()->Pos)
|
you may use GetMainViewport()->Pos to offset hard-coded positions, e.g. SetNextWindowPos(GetMainViewport()->Pos)
|
||||||
- likewise io.MousePos and GetMousePos() will use OS coordinates.
|
- likewise io.MousePos and GetMousePos() will use OS coordinates.
|
||||||
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
|
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
|
||||||
- 2019/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
|
- 2020/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
|
||||||
|
|
||||||
|
|
||||||
- 2020/04/23 (1.77) - Removed unnecessary ID (first arg) of ImFontAtlas::AddCustomRectRegular().
|
- 2020/06/23 (1.77) - removed BeginPopupContextWindow(const char*, int mouse_button, bool also_over_items) in favor of BeginPopupContextWindow(const char*, ImGuiPopupFlags flags) with ImGuiPopupFlags_NoOverItems.
|
||||||
|
- 2020/06/15 (1.77) - renamed OpenPopupOnItemClick() to OpenPopupContextItem(). Kept inline redirection function (will obsolete).
|
||||||
|
- 2020/06/15 (1.77) - removed CalcItemRectClosestPoint() entry point which was made obsolete and asserting in December 2017.
|
||||||
|
- 2020/04/23 (1.77) - removed unnecessary ID (first arg) of ImFontAtlas::AddCustomRectRegular().
|
||||||
- 2020/01/22 (1.75) - ImDrawList::AddCircle()/AddCircleFilled() functions don't accept negative radius any more.
|
- 2020/01/22 (1.75) - ImDrawList::AddCircle()/AddCircleFilled() functions don't accept negative radius any more.
|
||||||
- 2019/12/17 (1.75) - [undid this change in 1.76] made Columns() limited to 64 columns by asserting above that limit. While the current code technically supports it, future code may not so we're putting the restriction ahead.
|
- 2019/12/17 (1.75) - [undid this change in 1.76] made Columns() limited to 64 columns by asserting above that limit. While the current code technically supports it, future code may not so we're putting the restriction ahead.
|
||||||
- 2019/12/13 (1.75) - [imgui_internal.h] changed ImRect() default constructor initializes all fields to 0.0f instead of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by adding multiple points into it, you may need to fix your initial value.
|
- 2019/12/13 (1.75) - [imgui_internal.h] changed ImRect() default constructor initializes all fields to 0.0f instead of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by adding multiple points into it, you may need to fix your initial value.
|
||||||
@ -609,7 +612,10 @@ CODE
|
|||||||
FREQUENTLY ASKED QUESTIONS (FAQ)
|
FREQUENTLY ASKED QUESTIONS (FAQ)
|
||||||
================================
|
================================
|
||||||
|
|
||||||
Read all answers online: https://www.dearimgui.org/faq, or in docs/FAQ.md (with a Markdown viewer)
|
Read all answers online:
|
||||||
|
https://www.dearimgui.org/faq or https://github.com/ocornut/imgui/blob/master/docs/FAQ.md (same url)
|
||||||
|
Read all answers locally (with a text editor or ideally a Markdown viewer):
|
||||||
|
docs/FAQ.md
|
||||||
Some answers are copied down here to facilitate searching in code.
|
Some answers are copied down here to facilitate searching in code.
|
||||||
|
|
||||||
Q&A: Basics
|
Q&A: Basics
|
||||||
@ -631,143 +637,32 @@ CODE
|
|||||||
Q: What is this library called?
|
Q: What is this library called?
|
||||||
Q: Which version should I get?
|
Q: Which version should I get?
|
||||||
>> This library is called "Dear ImGui", please don't call it "ImGui" :)
|
>> This library is called "Dear ImGui", please don't call it "ImGui" :)
|
||||||
>> See https://www.dearimgui.org/faq
|
>> See https://www.dearimgui.org/faq for details.
|
||||||
|
|
||||||
Q&A: Integration
|
Q&A: Integration
|
||||||
================
|
================
|
||||||
|
|
||||||
|
Q: How to get started?
|
||||||
|
A: Read 'PROGRAMMER GUIDE' above. Read examples/README.txt.
|
||||||
|
|
||||||
Q: How can I tell whether to dispatch mouse/keyboard to Dear ImGui or to my application?
|
Q: How can I tell whether to dispatch mouse/keyboard to Dear ImGui or to my application?
|
||||||
A: You should read the 'io.WantCaptureMouse', 'io.WantCaptureKeyboard' and 'io.WantTextInput' flags!
|
A: You should read the 'io.WantCaptureMouse', 'io.WantCaptureKeyboard' and 'io.WantTextInput' flags!
|
||||||
>> See https://www.dearimgui.org/faq for fully detailed answer. You really want to read this.
|
>> See https://www.dearimgui.org/faq for fully detailed answer. You really want to read this.
|
||||||
|
|
||||||
Q. How can I enable keyboard controls?
|
Q. How can I enable keyboard controls?
|
||||||
Q: How can I use this without a mouse, without a keyboard or without a screen? (gamepad, input share, remote display)
|
Q: How can I use this without a mouse, without a keyboard or without a screen? (gamepad, input share, remote display)
|
||||||
Q: I integrated Dear ImGui in my engine and the text or lines are blurry..
|
Q: I integrated Dear ImGui in my engine and little squares are showing instead of text..
|
||||||
Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around..
|
Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around..
|
||||||
|
Q: I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries..
|
||||||
>> See https://www.dearimgui.org/faq
|
>> See https://www.dearimgui.org/faq
|
||||||
|
|
||||||
Q&A: Usage
|
Q&A: Usage
|
||||||
----------
|
----------
|
||||||
|
|
||||||
Q: Why are multiple widgets reacting when I interact with a single one?
|
Q: How can I have widgets with an empty label?
|
||||||
Q: How can I have multiple widgets with the same label or with an empty label?
|
Q: How can I have multiple widgets with the same label?
|
||||||
A: A primer on labels and the ID Stack...
|
Q: Why are multiple widgets reacting when I interact with one?
|
||||||
|
|
||||||
Dear ImGui internally need to uniquely identify UI elements.
|
|
||||||
Elements that are typically not clickable (such as calls to the Text functions) don't need an ID.
|
|
||||||
Interactive widgets (such as calls to Button buttons) need a unique ID.
|
|
||||||
Unique ID are used internally to track active widgets and occasionally associate state to widgets.
|
|
||||||
Unique ID are implicitly built from the hash of multiple elements that identify the "path" to the UI element.
|
|
||||||
|
|
||||||
- Unique ID are often derived from a string label:
|
|
||||||
|
|
||||||
Button("OK"); // Label = "OK", ID = hash of (..., "OK")
|
|
||||||
Button("Cancel"); // Label = "Cancel", ID = hash of (..., "Cancel")
|
|
||||||
|
|
||||||
- ID are uniquely scoped within windows, tree nodes, etc. which all pushes to the ID stack. Having
|
|
||||||
two buttons labeled "OK" in different windows or different tree locations is fine.
|
|
||||||
We used "..." above to signify whatever was already pushed to the ID stack previously:
|
|
||||||
|
|
||||||
Begin("MyWindow");
|
|
||||||
Button("OK"); // Label = "OK", ID = hash of ("MyWindow", "OK")
|
|
||||||
End();
|
|
||||||
Begin("MyOtherWindow");
|
|
||||||
Button("OK"); // Label = "OK", ID = hash of ("MyOtherWindow", "OK")
|
|
||||||
End();
|
|
||||||
|
|
||||||
- If you have a same ID twice in the same location, you'll have a conflict:
|
|
||||||
|
|
||||||
Button("OK");
|
|
||||||
Button("OK"); // ID collision! Interacting with either button will trigger the first one.
|
|
||||||
|
|
||||||
Fear not! this is easy to solve and there are many ways to solve it!
|
|
||||||
|
|
||||||
- Solving ID conflict in a simple/local context:
|
|
||||||
When passing a label you can optionally specify extra ID information within string itself.
|
|
||||||
Use "##" to pass a complement to the ID that won't be visible to the end-user.
|
|
||||||
This helps solving the simple collision cases when you know e.g. at compilation time which items
|
|
||||||
are going to be created:
|
|
||||||
|
|
||||||
Begin("MyWindow");
|
|
||||||
Button("Play"); // Label = "Play", ID = hash of ("MyWindow", "Play")
|
|
||||||
Button("Play##foo1"); // Label = "Play", ID = hash of ("MyWindow", "Play##foo1") // Different from above
|
|
||||||
Button("Play##foo2"); // Label = "Play", ID = hash of ("MyWindow", "Play##foo2") // Different from above
|
|
||||||
End();
|
|
||||||
|
|
||||||
- If you want to completely hide the label, but still need an ID:
|
|
||||||
|
|
||||||
Checkbox("##On", &b); // Label = "", ID = hash of (..., "##On") // No visible label, just a checkbox!
|
|
||||||
|
|
||||||
- Occasionally/rarely you might want change a label while preserving a constant ID. This allows
|
|
||||||
you to animate labels. For example you may want to include varying information in a window title bar,
|
|
||||||
but windows are uniquely identified by their ID. Use "###" to pass a label that isn't part of ID:
|
|
||||||
|
|
||||||
Button("Hello###ID"); // Label = "Hello", ID = hash of (..., "###ID")
|
|
||||||
Button("World###ID"); // Label = "World", ID = hash of (..., "###ID") // Same as above, even though the label looks different
|
|
||||||
|
|
||||||
sprintf(buf, "My game (%f FPS)###MyGame", fps);
|
|
||||||
Begin(buf); // Variable title, ID = hash of "MyGame"
|
|
||||||
|
|
||||||
- Solving ID conflict in a more general manner:
|
|
||||||
Use PushID() / PopID() to create scopes and manipulate the ID stack, as to avoid ID conflicts
|
|
||||||
within the same window. This is the most convenient way of distinguishing ID when iterating and
|
|
||||||
creating many UI elements programmatically.
|
|
||||||
You can push a pointer, a string or an integer value into the ID stack.
|
|
||||||
Remember that ID are formed from the concatenation of _everything_ pushed into the ID stack.
|
|
||||||
At each level of the stack we store the seed used for items at this level of the ID stack.
|
|
||||||
|
|
||||||
Begin("Window");
|
|
||||||
for (int i = 0; i < 100; i++)
|
|
||||||
{
|
|
||||||
PushID(i); // Push i to the id tack
|
|
||||||
Button("Click"); // Label = "Click", ID = hash of ("Window", i, "Click")
|
|
||||||
PopID();
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 100; i++)
|
|
||||||
{
|
|
||||||
MyObject* obj = Objects[i];
|
|
||||||
PushID(obj);
|
|
||||||
Button("Click"); // Label = "Click", ID = hash of ("Window", obj pointer, "Click")
|
|
||||||
PopID();
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 100; i++)
|
|
||||||
{
|
|
||||||
MyObject* obj = Objects[i];
|
|
||||||
PushID(obj->Name);
|
|
||||||
Button("Click"); // Label = "Click", ID = hash of ("Window", obj->Name, "Click")
|
|
||||||
PopID();
|
|
||||||
}
|
|
||||||
End();
|
|
||||||
|
|
||||||
- You can stack multiple prefixes into the ID stack:
|
|
||||||
|
|
||||||
Button("Click"); // Label = "Click", ID = hash of (..., "Click")
|
|
||||||
PushID("node");
|
|
||||||
Button("Click"); // Label = "Click", ID = hash of (..., "node", "Click")
|
|
||||||
PushID(my_ptr);
|
|
||||||
Button("Click"); // Label = "Click", ID = hash of (..., "node", my_ptr, "Click")
|
|
||||||
PopID();
|
|
||||||
PopID();
|
|
||||||
|
|
||||||
- Tree nodes implicitly creates a scope for you by calling PushID().
|
|
||||||
|
|
||||||
Button("Click"); // Label = "Click", ID = hash of (..., "Click")
|
|
||||||
if (TreeNode("node")) // <-- this function call will do a PushID() for you (unless instructed not to, with a special flag)
|
|
||||||
{
|
|
||||||
Button("Click"); // Label = "Click", ID = hash of (..., "node", "Click")
|
|
||||||
TreePop();
|
|
||||||
}
|
|
||||||
|
|
||||||
- When working with trees, ID are used to preserve the open/close state of each tree node.
|
|
||||||
Depending on your use cases you may want to use strings, indices or pointers as ID.
|
|
||||||
e.g. when following a single pointer that may change over time, using a static string as ID
|
|
||||||
will preserve your node open/closed state when the targeted object change.
|
|
||||||
e.g. when displaying a list of objects, using indices or pointers as ID will preserve the
|
|
||||||
node open/closed state differently. See what makes more sense in your situation!
|
|
||||||
|
|
||||||
Q: How can I display an image? What is ImTextureID, how does it works?
|
Q: How can I display an image? What is ImTextureID, how does it works?
|
||||||
>> See https://www.dearimgui.org/faq and https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples
|
|
||||||
|
|
||||||
Q: How can I use my own math types instead of ImVec2/ImVec4?
|
Q: How can I use my own math types instead of ImVec2/ImVec4?
|
||||||
Q: How can I interact with standard C++ types (such as std::string and std::vector)?
|
Q: How can I interact with standard C++ types (such as std::string and std::vector)?
|
||||||
Q: How can I display custom shapes? (using low-level ImDrawList API)
|
Q: How can I display custom shapes? (using low-level ImDrawList API)
|
||||||
@ -776,11 +671,12 @@ CODE
|
|||||||
Q&A: Fonts, Text
|
Q&A: Fonts, Text
|
||||||
================
|
================
|
||||||
|
|
||||||
|
Q: How should I handle DPI in my application?
|
||||||
Q: How can I load a different font than the default?
|
Q: How can I load a different font than the default?
|
||||||
Q: How can I easily use icons in my application?
|
Q: How can I easily use icons in my application?
|
||||||
Q: How can I load multiple fonts?
|
Q: How can I load multiple fonts?
|
||||||
Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
|
Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
|
||||||
>> See https://www.dearimgui.org/faq and docs/FONTS.txt
|
>> See https://www.dearimgui.org/faq and https://github.com/ocornut/imgui/edit/master/docs/FONTS.md
|
||||||
|
|
||||||
Q&A: Concerns
|
Q&A: Concerns
|
||||||
=============
|
=============
|
||||||
@ -871,21 +767,21 @@ CODE
|
|||||||
|
|
||||||
// Clang/GCC warnings with -Weverything
|
// Clang/GCC warnings with -Weverything
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning : unknown warning group '-Wformat-pedantic *' // not all warnings are known by all clang versions.. so ignoring warnings triggers new warnings on some configuration. great!
|
#if __has_warning("-Wunknown-warning-option")
|
||||||
|
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great!
|
||||||
|
#endif
|
||||||
|
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
|
||||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||||||
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
|
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
|
||||||
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
|
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
|
||||||
#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
|
#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
|
||||||
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is.
|
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is.
|
||||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness //
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||||
#pragma clang diagnostic ignored "-Wformat-pedantic" // warning: format specifies type 'void *' but the argument has type 'xxxx *' // unreasonable, would lead to casting every %p arg to void*. probably enabled by -pedantic.
|
#pragma clang diagnostic ignored "-Wformat-pedantic" // warning: format specifies type 'void *' but the argument has type 'xxxx *' // unreasonable, would lead to casting every %p arg to void*. probably enabled by -pedantic.
|
||||||
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning: cast to 'void *' from smaller integer type 'int'
|
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning: cast to 'void *' from smaller integer type 'int'
|
||||||
#if __has_warning("-Wzero-as-null-pointer-constant")
|
|
||||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
|
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
|
||||||
#endif
|
|
||||||
#if __has_warning("-Wdouble-promotion")
|
|
||||||
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
|
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
|
||||||
#endif
|
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
// We disable -Wpragmas because GCC doesn't provide an has_warning equivalent and some forks/patches may not following the warning/version association.
|
// We disable -Wpragmas because GCC doesn't provide an has_warning equivalent and some forks/patches may not following the warning/version association.
|
||||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||||
@ -967,7 +863,7 @@ static void UpdateMouseInputs();
|
|||||||
static void UpdateMouseWheel();
|
static void UpdateMouseWheel();
|
||||||
static void UpdateTabFocus();
|
static void UpdateTabFocus();
|
||||||
static void UpdateDebugToolItemPicker();
|
static void UpdateDebugToolItemPicker();
|
||||||
static bool UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]);
|
static bool UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect);
|
||||||
static void RenderWindowOuterBorders(ImGuiWindow* window);
|
static void RenderWindowOuterBorders(ImGuiWindow* window);
|
||||||
static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size);
|
static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size);
|
||||||
static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open);
|
static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open);
|
||||||
@ -1034,7 +930,7 @@ ImGuiStyle::ImGuiStyle()
|
|||||||
{
|
{
|
||||||
Alpha = 1.0f; // Global alpha applies to everything in ImGui
|
Alpha = 1.0f; // Global alpha applies to everything in ImGui
|
||||||
WindowPadding = ImVec2(8,8); // Padding within a window
|
WindowPadding = ImVec2(8,8); // Padding within a window
|
||||||
WindowRounding = 7.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows
|
WindowRounding = 7.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended.
|
||||||
WindowBorderSize = 1.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested.
|
WindowBorderSize = 1.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested.
|
||||||
WindowMinSize = ImVec2(32,32); // Minimum window size
|
WindowMinSize = ImVec2(32,32); // Minimum window size
|
||||||
WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text
|
WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text
|
||||||
@ -3046,7 +2942,7 @@ void ImGui::GcCompactTransientWindowBuffers(ImGuiWindow* window)
|
|||||||
window->MemoryDrawListIdxCapacity = window->DrawList->IdxBuffer.Capacity;
|
window->MemoryDrawListIdxCapacity = window->DrawList->IdxBuffer.Capacity;
|
||||||
window->MemoryDrawListVtxCapacity = window->DrawList->VtxBuffer.Capacity;
|
window->MemoryDrawListVtxCapacity = window->DrawList->VtxBuffer.Capacity;
|
||||||
window->IDStack.clear();
|
window->IDStack.clear();
|
||||||
window->DrawList->ClearFreeMemory();
|
window->DrawList->_ClearFreeMemory();
|
||||||
window->DC.ChildWindows.clear();
|
window->DC.ChildWindows.clear();
|
||||||
window->DC.ItemFlagsStack.clear();
|
window->DC.ItemFlagsStack.clear();
|
||||||
window->DC.ItemWidthStack.clear();
|
window->DC.ItemWidthStack.clear();
|
||||||
@ -3226,6 +3122,10 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
|
|||||||
if (window->DC.ItemFlags & ImGuiItemFlags_Disabled)
|
if (window->DC.ItemFlags & ImGuiItemFlags_Disabled)
|
||||||
return false;
|
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.
|
||||||
|
if (id != 0)
|
||||||
|
{
|
||||||
SetHoveredID(id);
|
SetHoveredID(id);
|
||||||
|
|
||||||
// [DEBUG] Item Picker tool!
|
// [DEBUG] Item Picker tool!
|
||||||
@ -3237,6 +3137,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
|
|||||||
GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 255, 0, 255));
|
GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 255, 0, 255));
|
||||||
if (g.DebugItemPickerBreakId == id)
|
if (g.DebugItemPickerBreakId == id)
|
||||||
IM_DEBUG_BREAK();
|
IM_DEBUG_BREAK();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -3301,11 +3202,21 @@ float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x)
|
|||||||
if (wrap_pos_x < 0.0f)
|
if (wrap_pos_x < 0.0f)
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
if (wrap_pos_x == 0.0f)
|
if (wrap_pos_x == 0.0f)
|
||||||
|
{
|
||||||
|
// We could decide to setup a default wrapping max point for auto-resizing windows,
|
||||||
|
// or have auto-wrap (with unspecified wrapping pos) behave as a ContentSize extending function?
|
||||||
|
//if (window->Hidden && (window->Flags & ImGuiWindowFlags_AlwaysAutoResize))
|
||||||
|
// wrap_pos_x = ImMax(window->WorkRect.Min.x + g.FontSize * 10.0f, window->WorkRect.Max.x);
|
||||||
|
//else
|
||||||
wrap_pos_x = window->WorkRect.Max.x;
|
wrap_pos_x = window->WorkRect.Max.x;
|
||||||
|
}
|
||||||
else if (wrap_pos_x > 0.0f)
|
else if (wrap_pos_x > 0.0f)
|
||||||
|
{
|
||||||
wrap_pos_x += window->Pos.x - window->Scroll.x; // wrap_pos_x is provided is window local space
|
wrap_pos_x += window->Pos.x - window->Scroll.x; // wrap_pos_x is provided is window local space
|
||||||
|
}
|
||||||
|
|
||||||
return ImMax(wrap_pos_x - pos.x, 1.0f);
|
return ImMax(wrap_pos_x - pos.x, 1.0f);
|
||||||
}
|
}
|
||||||
@ -3432,7 +3343,7 @@ static ImDrawList* GetViewportDrawList(ImGuiViewportP* viewport, size_t drawlist
|
|||||||
// Our ImDrawList system requires that there is always a command
|
// Our ImDrawList system requires that there is always a command
|
||||||
if (viewport->LastFrameDrawLists[drawlist_no] != g.FrameCount)
|
if (viewport->LastFrameDrawLists[drawlist_no] != g.FrameCount)
|
||||||
{
|
{
|
||||||
draw_list->Clear();
|
draw_list->_ResetForNewFrame();
|
||||||
draw_list->PushTextureID(g.IO.Fonts->TexID);
|
draw_list->PushTextureID(g.IO.Fonts->TexID);
|
||||||
draw_list->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size, false);
|
draw_list->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size, false);
|
||||||
viewport->LastFrameDrawLists[drawlist_no] = g.FrameCount;
|
viewport->LastFrameDrawLists[drawlist_no] = g.FrameCount;
|
||||||
@ -3593,8 +3504,12 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
|
|||||||
// (after we're done with all our widgets, so e.g. clicking on docking tab-bar which have set HoveredId already and not get us here!)
|
// (after we're done with all our widgets, so e.g. clicking on docking tab-bar which have set HoveredId already and not get us here!)
|
||||||
if (g.IO.MouseClicked[0])
|
if (g.IO.MouseClicked[0])
|
||||||
{
|
{
|
||||||
|
// Handle the edge case of a popup being closed while clicking in its empty space.
|
||||||
|
// If we try to focus it, FocusWindow() > ClosePopupsOverWindow() will accidentally close any parent popups because they are not linked together any more.
|
||||||
ImGuiWindow* root_window = g.HoveredWindow ? g.HoveredWindow->RootWindowDockStop : NULL;
|
ImGuiWindow* root_window = g.HoveredWindow ? g.HoveredWindow->RootWindowDockStop : NULL;
|
||||||
if (root_window != NULL)
|
const bool is_closed_popup = root_window && (root_window->Flags & ImGuiWindowFlags_Popup) && !IsPopupOpen(root_window->PopupId, ImGuiPopupFlags_AnyPopupLevel);
|
||||||
|
|
||||||
|
if (root_window != NULL && !is_closed_popup)
|
||||||
{
|
{
|
||||||
StartMouseMovingWindow(g.HoveredWindow);
|
StartMouseMovingWindow(g.HoveredWindow);
|
||||||
if (g.IO.ConfigWindowsMoveFromTitleBarOnly)
|
if (g.IO.ConfigWindowsMoveFromTitleBarOnly)
|
||||||
@ -3602,7 +3517,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
|
|||||||
if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
|
if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
|
||||||
g.MovingWindow = NULL;
|
g.MovingWindow = NULL;
|
||||||
}
|
}
|
||||||
else if (g.NavWindow != NULL && GetTopMostPopupModal() == NULL)
|
else if (root_window != NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL)
|
||||||
{
|
{
|
||||||
// Clicking on void disable focus
|
// Clicking on void disable focus
|
||||||
FocusWindow(NULL);
|
FocusWindow(NULL);
|
||||||
@ -3690,7 +3605,7 @@ static void ImGui::UpdateMouseInputs()
|
|||||||
ImVec2 delta_from_click_pos = IsMousePosValid(&g.IO.MousePos) ? (g.IO.MousePos - g.IO.MouseClickedPos[i]) : ImVec2(0.0f, 0.0f);
|
ImVec2 delta_from_click_pos = IsMousePosValid(&g.IO.MousePos) ? (g.IO.MousePos - g.IO.MouseClickedPos[i]) : ImVec2(0.0f, 0.0f);
|
||||||
if (ImLengthSqr(delta_from_click_pos) < g.IO.MouseDoubleClickMaxDist * g.IO.MouseDoubleClickMaxDist)
|
if (ImLengthSqr(delta_from_click_pos) < g.IO.MouseDoubleClickMaxDist * g.IO.MouseDoubleClickMaxDist)
|
||||||
g.IO.MouseDoubleClicked[i] = true;
|
g.IO.MouseDoubleClicked[i] = true;
|
||||||
g.IO.MouseClickedTime[i] = -DBL_MAX; // so the third click isn't turned into a double-click
|
g.IO.MouseClickedTime[i] = -g.IO.MouseDoubleClickTime * 2.0f; // Mark as "old enough" so the third click isn't turned into a double-click
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3866,7 +3781,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
|||||||
for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++)
|
for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++)
|
||||||
{
|
{
|
||||||
if (g.IO.MouseClicked[i])
|
if (g.IO.MouseClicked[i])
|
||||||
g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (!g.OpenPopupStack.empty());
|
g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (g.OpenPopupStack.Size > 0);
|
||||||
mouse_any_down |= g.IO.MouseDown[i];
|
mouse_any_down |= g.IO.MouseDown[i];
|
||||||
if (g.IO.MouseDown[i])
|
if (g.IO.MouseDown[i])
|
||||||
if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[i] < g.IO.MouseClickedTime[mouse_earliest_button_down])
|
if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[i] < g.IO.MouseClickedTime[mouse_earliest_button_down])
|
||||||
@ -3884,7 +3799,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
|||||||
if (g.WantCaptureMouseNextFrame != -1)
|
if (g.WantCaptureMouseNextFrame != -1)
|
||||||
g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0);
|
g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0);
|
||||||
else
|
else
|
||||||
g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (!g.OpenPopupStack.empty());
|
g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (g.OpenPopupStack.Size > 0);
|
||||||
|
|
||||||
// Update io.WantCaptureKeyboard for the user application (true = dispatch keyboard info to imgui, false = dispatch keyboard info to Dear ImGui + app)
|
// Update io.WantCaptureKeyboard for the user application (true = dispatch keyboard info to imgui, false = dispatch keyboard info to Dear ImGui + app)
|
||||||
if (g.WantCaptureKeyboardNextFrame != -1)
|
if (g.WantCaptureKeyboardNextFrame != -1)
|
||||||
@ -4208,6 +4123,11 @@ void ImGui::Shutdown(ImGuiContext* context)
|
|||||||
// Shutdown extensions
|
// Shutdown extensions
|
||||||
DockContextShutdown(&g);
|
DockContextShutdown(&g);
|
||||||
|
|
||||||
|
// Notify hooked test engine, if any
|
||||||
|
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||||
|
ImGuiTestEngineHook_Shutdown(context);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Clear everything else
|
// Clear everything else
|
||||||
for (int i = 0; i < g.Windows.Size; i++)
|
for (int i = 0; i < g.Windows.Size; i++)
|
||||||
IM_DELETE(g.Windows[i]);
|
IM_DELETE(g.Windows[i]);
|
||||||
@ -4287,18 +4207,12 @@ static void AddWindowToSortBuffer(ImVector<ImGuiWindow*>* out_sorted_windows, Im
|
|||||||
|
|
||||||
static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* draw_list)
|
static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* draw_list)
|
||||||
{
|
{
|
||||||
if (draw_list->CmdBuffer.empty())
|
// Remove trailing command if unused.
|
||||||
|
// Technically we could return directly instead of popping, but this make things looks neat in Metrics window as well.
|
||||||
|
draw_list->_PopUnusedDrawCmd();
|
||||||
|
if (draw_list->CmdBuffer.Size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Remove trailing command if unused
|
|
||||||
ImDrawCmd& last_cmd = draw_list->CmdBuffer.back();
|
|
||||||
if (last_cmd.ElemCount == 0 && last_cmd.UserCallback == NULL)
|
|
||||||
{
|
|
||||||
draw_list->CmdBuffer.pop_back();
|
|
||||||
if (draw_list->CmdBuffer.empty())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc.
|
// Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc.
|
||||||
// May trigger for you if you are using PrimXXX functions incorrectly.
|
// May trigger for you if you are using PrimXXX functions incorrectly.
|
||||||
IM_ASSERT(draw_list->VtxBuffer.Size == 0 || draw_list->_VtxWritePtr == draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size);
|
IM_ASSERT(draw_list->VtxBuffer.Size == 0 || draw_list->_VtxWritePtr == draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size);
|
||||||
@ -4391,7 +4305,12 @@ static void SetupViewportDrawData(ImGuiViewportP* viewport, ImVector<ImDrawList*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When using this function it is sane to ensure that float are perfectly rounded to integer values, to that e.g. (int)(max.x-min.x) in user's render produce correct result.
|
// Push a clipping rectangle for both ImGui logic (hit-testing etc.) and low-level ImDrawList rendering.
|
||||||
|
// - When using this function it is sane to ensure that float are perfectly rounded to integer values,
|
||||||
|
// so that e.g. (int)(max.x-min.x) in user's render produce correct result.
|
||||||
|
// - If the code here changes, may need to update code of functions like NextColumn() and PushColumnClipRect():
|
||||||
|
// some frequently called functions which to modify both channels and clipping simultaneously tend to use the
|
||||||
|
// more specialized SetWindowClipRectBeforeSetChannel() to avoid extraneous updates of underlying ImDrawCmds.
|
||||||
void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect)
|
void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
@ -5442,10 +5361,10 @@ static ImRect GetResizeBorderRect(ImGuiWindow* window, int border_n, float perp_
|
|||||||
{
|
{
|
||||||
ImRect rect = window->Rect();
|
ImRect rect = window->Rect();
|
||||||
if (thickness == 0.0f) rect.Max -= ImVec2(1, 1);
|
if (thickness == 0.0f) rect.Max -= ImVec2(1, 1);
|
||||||
if (border_n == 0) return ImRect(rect.Min.x + perp_padding, rect.Min.y - thickness, rect.Max.x - perp_padding, rect.Min.y + thickness); // Top
|
if (border_n == 0) { return ImRect(rect.Min.x + perp_padding, rect.Min.y - thickness, rect.Max.x - perp_padding, rect.Min.y + thickness); } // Top
|
||||||
if (border_n == 1) return ImRect(rect.Max.x - thickness, rect.Min.y + perp_padding, rect.Max.x + thickness, rect.Max.y - perp_padding); // Right
|
if (border_n == 1) { return ImRect(rect.Max.x - thickness, rect.Min.y + perp_padding, rect.Max.x + thickness, rect.Max.y - perp_padding); } // Right
|
||||||
if (border_n == 2) return ImRect(rect.Min.x + perp_padding, rect.Max.y - thickness, rect.Max.x - perp_padding, rect.Max.y + thickness); // Bottom
|
if (border_n == 2) { return ImRect(rect.Min.x + perp_padding, rect.Max.y - thickness, rect.Max.x - perp_padding, rect.Max.y + thickness); } // Bottom
|
||||||
if (border_n == 3) return ImRect(rect.Min.x - thickness, rect.Min.y + perp_padding, rect.Min.x + thickness, rect.Max.y - perp_padding); // Left
|
if (border_n == 3) { return ImRect(rect.Min.x - thickness, rect.Min.y + perp_padding, rect.Min.x + thickness, rect.Max.y - perp_padding); } // Left
|
||||||
IM_ASSERT(0);
|
IM_ASSERT(0);
|
||||||
return ImRect();
|
return ImRect();
|
||||||
}
|
}
|
||||||
@ -5463,7 +5382,7 @@ ImGuiID ImGui::GetWindowResizeID(ImGuiWindow* window, int n)
|
|||||||
|
|
||||||
// Handle resize for: Resize Grips, Borders, Gamepad
|
// Handle resize for: Resize Grips, Borders, Gamepad
|
||||||
// Return true when using auto-fit (double click on resize grip)
|
// Return true when using auto-fit (double click on resize grip)
|
||||||
static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4])
|
static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindowFlags flags = window->Flags;
|
ImGuiWindowFlags flags = window->Flags;
|
||||||
@ -5487,9 +5406,10 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
|||||||
// This is however not the case with current back-ends under Win32, but a custom borderless window implementation would benefit from it.
|
// This is however not the case with current back-ends under Win32, but a custom borderless window implementation would benefit from it.
|
||||||
// - When decoration are enabled we typically benefit from that distance, but then our resize elements would be conflicting with OS resize elements, so we also narrow.
|
// - When decoration are enabled we typically benefit from that distance, but then our resize elements would be conflicting with OS resize elements, so we also narrow.
|
||||||
// - Note that we are unable to tell if the platform setup allows hovering with a distance threshold (on Win32, decorated window have such threshold).
|
// - Note that we are unable to tell if the platform setup allows hovering with a distance threshold (on Win32, decorated window have such threshold).
|
||||||
|
// We only clip interaction so we overwrite window->ClipRect, cannot call PushClipRect() yet as DrawList is not yet setup.
|
||||||
const bool clip_with_viewport_rect = !(g.IO.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport) || (g.IO.MouseHoveredViewport != window->ViewportId) || !(window->Viewport->Flags & ImGuiViewportFlags_NoDecoration);
|
const bool clip_with_viewport_rect = !(g.IO.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport) || (g.IO.MouseHoveredViewport != window->ViewportId) || !(window->Viewport->Flags & ImGuiViewportFlags_NoDecoration);
|
||||||
if (clip_with_viewport_rect)
|
if (clip_with_viewport_rect)
|
||||||
PushClipRect(window->Viewport->Pos, window->Viewport->Pos + window->Viewport->Size, true); // Won't incur a draw command as we are not drawing here.
|
window->ClipRect = window->Viewport->GetMainRect();
|
||||||
|
|
||||||
// Resize grips and borders are on layer 1
|
// Resize grips and borders are on layer 1
|
||||||
window->DC.NavLayerCurrent = ImGuiNavLayer_Menu;
|
window->DC.NavLayerCurrent = ImGuiNavLayer_Menu;
|
||||||
@ -5524,6 +5444,9 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
|||||||
// Resize from any of the four corners
|
// Resize from any of the four corners
|
||||||
// We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
|
// We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
|
||||||
ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + ImLerp(grip.InnerDir * grip_hover_outer_size, grip.InnerDir * -grip_hover_inner_size, grip.CornerPosN); // Corner of the window corresponding to our corner grip
|
ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + ImLerp(grip.InnerDir * grip_hover_outer_size, grip.InnerDir * -grip_hover_inner_size, grip.CornerPosN); // Corner of the window corresponding to our corner grip
|
||||||
|
ImVec2 clamp_min = ImVec2(grip.CornerPosN.x == 1.0f ? visibility_rect.Min.x : -FLT_MAX, grip.CornerPosN.y == 1.0f ? visibility_rect.Min.y : -FLT_MAX);
|
||||||
|
ImVec2 clamp_max = ImVec2(grip.CornerPosN.x == 0.0f ? visibility_rect.Max.x : +FLT_MAX, grip.CornerPosN.y == 0.0f ? visibility_rect.Max.y : +FLT_MAX);
|
||||||
|
corner_target = ImClamp(corner_target, clamp_min, clamp_max);
|
||||||
CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPosN, &pos_target, &size_target);
|
CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPosN, &pos_target, &size_target);
|
||||||
}
|
}
|
||||||
if (resize_grip_n == 0 || held || hovered)
|
if (resize_grip_n == 0 || held || hovered)
|
||||||
@ -5549,12 +5472,13 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
|||||||
if (border_n == 1) { border_posn = ImVec2(1, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Right
|
if (border_n == 1) { border_posn = ImVec2(1, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Right
|
||||||
if (border_n == 2) { border_posn = ImVec2(0, 1); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Bottom
|
if (border_n == 2) { border_posn = ImVec2(0, 1); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Bottom
|
||||||
if (border_n == 3) { border_posn = ImVec2(0, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Left
|
if (border_n == 3) { border_posn = ImVec2(0, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Left
|
||||||
|
ImVec2 clamp_min = ImVec2(border_n == 1 ? visibility_rect.Min.x : -FLT_MAX, border_n == 2 ? visibility_rect.Min.y : -FLT_MAX);
|
||||||
|
ImVec2 clamp_max = ImVec2(border_n == 3 ? visibility_rect.Max.x : +FLT_MAX, border_n == 0 ? visibility_rect.Max.y : +FLT_MAX);
|
||||||
|
border_target = ImClamp(border_target, clamp_min, clamp_max);
|
||||||
CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target);
|
CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PopID();
|
PopID();
|
||||||
if (clip_with_viewport_rect)
|
|
||||||
PopClipRect();
|
|
||||||
|
|
||||||
// Restore nav layer
|
// Restore nav layer
|
||||||
window->DC.NavLayerCurrent = ImGuiNavLayer_Main;
|
window->DC.NavLayerCurrent = ImGuiNavLayer_Main;
|
||||||
@ -5572,6 +5496,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
|||||||
{
|
{
|
||||||
const float NAV_RESIZE_SPEED = 600.0f;
|
const float NAV_RESIZE_SPEED = 600.0f;
|
||||||
nav_resize_delta *= ImFloor(NAV_RESIZE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y));
|
nav_resize_delta *= ImFloor(NAV_RESIZE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y));
|
||||||
|
nav_resize_delta = ImMax(nav_resize_delta, visibility_rect.Min - window->Pos - window->Size);
|
||||||
g.NavWindowingToggleLayer = false;
|
g.NavWindowingToggleLayer = false;
|
||||||
g.NavDisableMouseHover = true;
|
g.NavDisableMouseHover = true;
|
||||||
resize_grip_col[0] = GetColorU32(ImGuiCol_ResizeGripActive);
|
resize_grip_col[0] = GetColorU32(ImGuiCol_ResizeGripActive);
|
||||||
@ -5596,11 +5521,13 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
|||||||
return ret_auto_fit;
|
return ret_auto_fit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& rect, const ImVec2& padding)
|
static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& visibility_rect)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImVec2 size_for_clamping = (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar)) ? ImVec2(window->Size.x, window->TitleBarHeight()) : window->Size;
|
ImVec2 size_for_clamping = window->Size;
|
||||||
window->Pos = ImMin(rect.Max - padding, ImMax(window->Pos + size_for_clamping, rect.Min + padding) - size_for_clamping);
|
if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar))
|
||||||
|
size_for_clamping.y = window->TitleBarHeight();
|
||||||
|
window->Pos = ImClamp(window->Pos, visibility_rect.Min - size_for_clamping, visibility_rect.Max);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
|
static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
|
||||||
@ -6030,6 +5957,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
window->HasCloseButton = (p_open != NULL);
|
window->HasCloseButton = (p_open != NULL);
|
||||||
window->ClipRect = ImVec4(-FLT_MAX, -FLT_MAX, +FLT_MAX, +FLT_MAX);
|
window->ClipRect = ImVec4(-FLT_MAX, -FLT_MAX, +FLT_MAX, +FLT_MAX);
|
||||||
window->IDStack.resize(1);
|
window->IDStack.resize(1);
|
||||||
|
window->DrawList->_ResetForNewFrame();
|
||||||
|
|
||||||
// Restore buffer capacity when woken from a compacted state, to avoid
|
// Restore buffer capacity when woken from a compacted state, to avoid
|
||||||
if (window->MemoryCompacted)
|
if (window->MemoryCompacted)
|
||||||
@ -6174,7 +6102,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
if (window_just_activated_by_user)
|
if (window_just_activated_by_user)
|
||||||
{
|
{
|
||||||
window->AutoPosLastDirection = ImGuiDir_None;
|
window->AutoPosLastDirection = ImGuiDir_None;
|
||||||
if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api)
|
if ((flags & ImGuiWindowFlags_Popup) != 0 && !(flags & ImGuiWindowFlags_Modal) && !window_pos_set_by_api) // FIXME: BeginPopup() could use SetNextWindowPos()
|
||||||
window->Pos = g.BeginPopupStack.back().OpenPopupPos;
|
window->Pos = g.BeginPopupStack.back().OpenPopupPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6283,16 +6211,21 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
window->Viewport->Flags = viewport_flags;
|
window->Viewport->Flags = viewport_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate the range of allowed position for that window (to be movable and visible past safe area padding)
|
||||||
|
// When clamping to stay visible, we will enforce that window->Pos stays inside of visibility_rect.
|
||||||
|
ImRect viewport_rect(window->Viewport->GetMainRect());
|
||||||
|
ImRect viewport_work_rect(window->Viewport->GetWorkRect());
|
||||||
|
ImVec2 visibility_padding = ImMax(style.DisplayWindowPadding, style.DisplaySafeAreaPadding);
|
||||||
|
ImRect visibility_rect(viewport_work_rect.Min + visibility_padding, viewport_work_rect.Max - visibility_padding);
|
||||||
|
|
||||||
// Clamp position/size so window stays visible within its viewport or monitor
|
// Clamp position/size so window stays visible within its viewport or monitor
|
||||||
// Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing.
|
// Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing.
|
||||||
// FIXME: Similar to code in GetWindowAllowedExtentRect()
|
// FIXME: Similar to code in GetWindowAllowedExtentRect()
|
||||||
ImRect viewport_rect = window->Viewport->GetMainRect();
|
|
||||||
if (!window_pos_set_by_api && !(flags & ImGuiWindowFlags_ChildWindow) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
|
if (!window_pos_set_by_api && !(flags & ImGuiWindowFlags_ChildWindow) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
|
||||||
{
|
{
|
||||||
ImVec2 clamp_padding = ImMax(style.DisplayWindowPadding, style.DisplaySafeAreaPadding);
|
|
||||||
if (!window->ViewportOwned && viewport_rect.GetWidth() > 0 && viewport_rect.GetHeight() > 0.0f)
|
if (!window->ViewportOwned && viewport_rect.GetWidth() > 0 && viewport_rect.GetHeight() > 0.0f)
|
||||||
{
|
{
|
||||||
ClampWindowRect(window, window->Viewport->GetWorkRect(), clamp_padding);
|
ClampWindowRect(window, visibility_rect);
|
||||||
}
|
}
|
||||||
else if (window->ViewportOwned && g.PlatformIO.Monitors.Size > 0)
|
else if (window->ViewportOwned && g.PlatformIO.Monitors.Size > 0)
|
||||||
{
|
{
|
||||||
@ -6304,18 +6237,25 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ImGuiPlatformMonitor& monitor = g.PlatformIO.Monitors[window->Viewport->PlatformMonitor];
|
ImGuiPlatformMonitor& monitor = g.PlatformIO.Monitors[window->Viewport->PlatformMonitor];
|
||||||
ClampWindowRect(window, ImRect(monitor.WorkPos, monitor.WorkPos + monitor.WorkSize), clamp_padding);
|
visibility_rect.Min = monitor.WorkPos + visibility_padding;
|
||||||
|
visibility_rect.Max = monitor.WorkPos + monitor.WorkSize - visibility_padding;
|
||||||
|
ClampWindowRect(window, visibility_rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window->Pos = ImFloor(window->Pos);
|
window->Pos = ImFloor(window->Pos);
|
||||||
|
|
||||||
// Lock window rounding for the frame (so that altering them doesn't cause inconsistencies)
|
// Lock window rounding for the frame (so that altering them doesn't cause inconsistencies)
|
||||||
|
// Large values tend to lead to variety of artifacts and are not recommended.
|
||||||
if (window->ViewportOwned || window->DockIsActive)
|
if (window->ViewportOwned || window->DockIsActive)
|
||||||
window->WindowRounding = 0.0f;
|
window->WindowRounding = 0.0f;
|
||||||
else
|
else
|
||||||
window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding;
|
window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding;
|
||||||
|
|
||||||
|
// For windows with title bar or menu bar, we clamp to FrameHeight(FontSize + FramePadding.y * 2.0f) to completely hide artifacts.
|
||||||
|
//if ((window->Flags & ImGuiWindowFlags_MenuBar) || !(window->Flags & ImGuiWindowFlags_NoTitleBar))
|
||||||
|
// window->WindowRounding = ImMin(window->WindowRounding, g.FontSize + style.FramePadding.y * 2.0f);
|
||||||
|
|
||||||
// Apply window focus (new and reactivated windows are moved to front)
|
// Apply window focus (new and reactivated windows are moved to front)
|
||||||
bool want_focus = false;
|
bool want_focus = false;
|
||||||
if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing))
|
if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing))
|
||||||
@ -6335,7 +6275,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
|
const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
|
||||||
const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
||||||
if (handle_borders_and_resize_grips && !window->Collapsed)
|
if (handle_borders_and_resize_grips && !window->Collapsed)
|
||||||
if (UpdateWindowManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]))
|
if (UpdateWindowManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0], visibility_rect))
|
||||||
use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true;
|
use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true;
|
||||||
window->ResizeBorderHeld = (signed char)border_held;
|
window->ResizeBorderHeld = (signed char)border_held;
|
||||||
|
|
||||||
@ -6435,7 +6375,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
// DRAWING
|
// DRAWING
|
||||||
|
|
||||||
// Setup draw list and outer clipping rectangle
|
// Setup draw list and outer clipping rectangle
|
||||||
window->DrawList->Clear();
|
IM_ASSERT(window->DrawList->CmdBuffer.Size == 1 && window->DrawList->CmdBuffer[0].ElemCount == 0);
|
||||||
window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID);
|
window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID);
|
||||||
PushClipRect(host_rect.Min, host_rect.Max, false);
|
PushClipRect(host_rect.Min, host_rect.Max, false);
|
||||||
|
|
||||||
@ -7568,9 +7508,8 @@ static void ImGui::ErrorCheckNewFrameSanityChecks()
|
|||||||
for (int monitor_n = 0; monitor_n < g.PlatformIO.Monitors.Size; monitor_n++)
|
for (int monitor_n = 0; monitor_n < g.PlatformIO.Monitors.Size; monitor_n++)
|
||||||
{
|
{
|
||||||
ImGuiPlatformMonitor& mon = g.PlatformIO.Monitors[monitor_n];
|
ImGuiPlatformMonitor& mon = g.PlatformIO.Monitors[monitor_n];
|
||||||
IM_UNUSED(mon);
|
IM_ASSERT(mon.MainSize.x > 0.0f && mon.MainSize.y > 0.0f && "Monitor main bounds not setup properly.");
|
||||||
IM_ASSERT(mon.MainSize.x > 0.0f && mon.MainSize.y > 0.0f && "Monitor bounds not setup properly.");
|
IM_ASSERT(ImRect(mon.MainPos, mon.MainPos + mon.MainSize).Contains(ImRect(mon.WorkPos, mon.WorkPos + mon.WorkSize)) && "Monitor work bounds not setup properly. If you don't have work area information, just copy MainPos/MainSize into them.");
|
||||||
IM_ASSERT(mon.WorkSize.x > 0.0f && mon.WorkSize.y > 0.0f && "Monitor bounds not setup properly. If you don't have work area information, just copy Min/Max into them.");
|
|
||||||
IM_ASSERT(mon.DpiScale != 0.0f);
|
IM_ASSERT(mon.DpiScale != 0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8336,16 +8275,45 @@ void ImGui::SetTooltip(const char* fmt, ...)
|
|||||||
// [SECTION] POPUPS
|
// [SECTION] POPUPS
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool ImGui::IsPopupOpen(ImGuiID id)
|
// Supported flags: ImGuiPopupFlags_AnyPopupId, ImGuiPopupFlags_AnyPopupLevel
|
||||||
|
bool ImGui::IsPopupOpen(ImGuiID id, ImGuiPopupFlags popup_flags)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
if (popup_flags & ImGuiPopupFlags_AnyPopupId)
|
||||||
|
{
|
||||||
|
// Return true if any popup is open at the current BeginPopup() level of the popup stack
|
||||||
|
// This may be used to e.g. test for another popups already opened to handle popups priorities at the same level.
|
||||||
|
IM_ASSERT(id == 0);
|
||||||
|
if (popup_flags & ImGuiPopupFlags_AnyPopupLevel)
|
||||||
|
return g.OpenPopupStack.Size > 0;
|
||||||
|
else
|
||||||
|
return g.OpenPopupStack.Size > g.BeginPopupStack.Size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (popup_flags & ImGuiPopupFlags_AnyPopupLevel)
|
||||||
|
{
|
||||||
|
// Return true if the popup is open anywhere in the popup stack
|
||||||
|
for (int n = 0; n < g.OpenPopupStack.Size; n++)
|
||||||
|
if (g.OpenPopupStack[n].PopupId == id)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Return true if the popup is open at the current BeginPopup() level of the popup stack (this is the most-common query)
|
||||||
return g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].PopupId == id;
|
return g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].PopupId == id;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ImGui::IsPopupOpen(const char* str_id)
|
bool ImGui::IsPopupOpen(const char* str_id, ImGuiPopupFlags popup_flags)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
return g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].PopupId == g.CurrentWindow->GetID(str_id);
|
ImGuiID id = (popup_flags & ImGuiPopupFlags_AnyPopupId) ? 0 : g.CurrentWindow->GetID(str_id);
|
||||||
|
if ((popup_flags & ImGuiPopupFlags_AnyPopupLevel) && id != 0)
|
||||||
|
IM_ASSERT(0 && "Cannot use IsPopupOpen() with a string id and ImGuiPopupFlags_AnyPopupLevel."); // But non-string version is legal and used internally
|
||||||
|
return IsPopupOpen(id, popup_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiWindow* ImGui::GetTopMostPopupModal()
|
ImGuiWindow* ImGui::GetTopMostPopupModal()
|
||||||
@ -8358,21 +8326,26 @@ ImGuiWindow* ImGui::GetTopMostPopupModal()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::OpenPopup(const char* str_id)
|
void ImGui::OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
OpenPopupEx(g.CurrentWindow->GetID(str_id));
|
OpenPopupEx(g.CurrentWindow->GetID(str_id), popup_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark popup as open (toggle toward open state).
|
// Mark popup as open (toggle toward open state).
|
||||||
// Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block.
|
// Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block.
|
||||||
// Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level).
|
// Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level).
|
||||||
// One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL)
|
// One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL)
|
||||||
void ImGui::OpenPopupEx(ImGuiID id)
|
void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* parent_window = g.CurrentWindow;
|
ImGuiWindow* parent_window = g.CurrentWindow;
|
||||||
int current_stack_size = g.BeginPopupStack.Size;
|
const int current_stack_size = g.BeginPopupStack.Size;
|
||||||
|
|
||||||
|
if (popup_flags & ImGuiPopupFlags_NoOpenOverExistingPopup)
|
||||||
|
if (IsPopupOpen(0u, ImGuiPopupFlags_AnyPopupId))
|
||||||
|
return;
|
||||||
|
|
||||||
ImGuiPopupData popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack.
|
ImGuiPopupData popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack.
|
||||||
popup_ref.PopupId = id;
|
popup_ref.PopupId = id;
|
||||||
popup_ref.Window = NULL;
|
popup_ref.Window = NULL;
|
||||||
@ -8399,8 +8372,8 @@ void ImGui::OpenPopupEx(ImGuiID id)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Close child popups if any, then flag popup for open/reopen
|
// Close child popups if any, then flag popup for open/reopen
|
||||||
g.OpenPopupStack.resize(current_stack_size + 1);
|
ClosePopupToLevel(current_stack_size, false);
|
||||||
g.OpenPopupStack[current_stack_size] = popup_ref;
|
g.OpenPopupStack.push_back(popup_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When reopening a popup we first refocus its parent, otherwise if its parent is itself a popup it would get closed by ClosePopupsOverWindow().
|
// When reopening a popup we first refocus its parent, otherwise if its parent is itself a popup it would get closed by ClosePopupsOverWindow().
|
||||||
@ -8413,7 +8386,7 @@ void ImGui::OpenPopupEx(ImGuiID id)
|
|||||||
void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup)
|
void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (g.OpenPopupStack.empty())
|
if (g.OpenPopupStack.Size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it.
|
// When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it.
|
||||||
@ -8453,6 +8426,8 @@ void ImGui::ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
IMGUI_DEBUG_LOG_POPUP("ClosePopupToLevel(%d), restore_focus_to_window_under_popup=%d\n", remaining, restore_focus_to_window_under_popup);
|
IMGUI_DEBUG_LOG_POPUP("ClosePopupToLevel(%d), restore_focus_to_window_under_popup=%d\n", remaining, restore_focus_to_window_under_popup);
|
||||||
IM_ASSERT(remaining >= 0 && remaining < g.OpenPopupStack.Size);
|
IM_ASSERT(remaining >= 0 && remaining < g.OpenPopupStack.Size);
|
||||||
|
|
||||||
|
// Trim open popup stack
|
||||||
ImGuiWindow* focus_window = g.OpenPopupStack[remaining].SourceWindow;
|
ImGuiWindow* focus_window = g.OpenPopupStack[remaining].SourceWindow;
|
||||||
ImGuiWindow* popup_window = g.OpenPopupStack[remaining].Window;
|
ImGuiWindow* popup_window = g.OpenPopupStack[remaining].Window;
|
||||||
g.OpenPopupStack.resize(remaining);
|
g.OpenPopupStack.resize(remaining);
|
||||||
@ -8504,10 +8479,11 @@ void ImGui::CloseCurrentPopup()
|
|||||||
window->DC.NavHideHighlightOneFrame = true;
|
window->DC.NavHideHighlightOneFrame = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attention! BeginPopup() adds default flags which BeginPopupEx()!
|
||||||
bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags flags)
|
bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags flags)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (!IsPopupOpen(id))
|
if (!IsPopupOpen(id, ImGuiPopupFlags_None))
|
||||||
{
|
{
|
||||||
g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
|
g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
|
||||||
return false;
|
return false;
|
||||||
@ -8546,21 +8522,22 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags fla
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
const ImGuiID id = window->GetID(name);
|
const ImGuiID id = window->GetID(name);
|
||||||
if (!IsPopupOpen(id))
|
if (!IsPopupOpen(id, ImGuiPopupFlags_None))
|
||||||
{
|
{
|
||||||
g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
|
g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Center modal windows by default
|
// Center modal windows by default for increased visibility
|
||||||
|
// (this won't really last as settings will kick in, and is mostly for backward compatibility. user may do the same themselves)
|
||||||
// FIXME: Should test for (PosCond & window->SetWindowPosAllowFlags) with the upcoming window.
|
// FIXME: Should test for (PosCond & window->SetWindowPosAllowFlags) with the upcoming window.
|
||||||
if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) == 0)
|
if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) == 0)
|
||||||
{
|
{
|
||||||
ImGuiViewportP* viewport = window->WasActive ? window->Viewport : (ImGuiViewportP*)GetMainViewport(); // FIXME-VIEWPORT: What may be our reference viewport?
|
ImGuiViewportP* viewport = window->WasActive ? window->Viewport : (ImGuiViewportP*)GetMainViewport(); // FIXME-VIEWPORT: What may be our reference viewport?
|
||||||
SetNextWindowPos(viewport->GetMainRect().GetCenter(), ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
SetNextWindowPos(viewport->GetMainRect().GetCenter(), ImGuiCond_FirstUseEver, ImVec2(0.5f, 0.5f));
|
||||||
}
|
}
|
||||||
|
|
||||||
flags |= ImGuiWindowFlags_Popup | ImGuiWindowFlags_Modal | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoDocking;
|
flags |= ImGuiWindowFlags_Popup | ImGuiWindowFlags_Modal | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoDocking;
|
||||||
const bool is_open = Begin(name, p_open, flags);
|
const bool is_open = Begin(name, p_open, flags);
|
||||||
if (!is_open || (p_open && !*p_open)) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
|
if (!is_open || (p_open && !*p_open)) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
|
||||||
{
|
{
|
||||||
@ -8591,52 +8568,61 @@ void ImGui::EndPopup()
|
|||||||
g.WithinEndChild = false;
|
g.WithinEndChild = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui::OpenPopupOnItemClick(const char* str_id, ImGuiMouseButton mouse_button)
|
bool ImGui::OpenPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flags)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||||
|
int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_);
|
||||||
if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
|
if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
|
||||||
{
|
{
|
||||||
ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict!
|
ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict!
|
||||||
IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item)
|
IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item)
|
||||||
OpenPopupEx(id);
|
OpenPopupEx(id, popup_flags);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a helper to handle the simplest case of associating one named popup to one given widget.
|
// This is a helper to handle the simplest case of associating one named popup to one given widget.
|
||||||
// You may want to handle this on user side if you have specific needs (e.g. tweaking IsItemHovered() parameters).
|
// - You can pass a NULL str_id to use the identifier of the last item.
|
||||||
// You can pass a NULL str_id to use the identifier of the last item.
|
// - You may want to handle this on user side if you have specific needs (e.g. tweaking IsItemHovered() parameters).
|
||||||
bool ImGui::BeginPopupContextItem(const char* str_id, ImGuiMouseButton mouse_button)
|
// - This is essentially the same as calling OpenPopupContextItem() + BeginPopup() but written to avoid
|
||||||
|
// computing the ID twice because BeginPopupContextXXX functions are called very frequently.
|
||||||
|
bool ImGui::BeginPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flags)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||||
if (window->SkipItems)
|
if (window->SkipItems)
|
||||||
return false;
|
return false;
|
||||||
ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict!
|
ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict!
|
||||||
IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item)
|
IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item)
|
||||||
|
int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_);
|
||||||
if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
|
if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
|
||||||
OpenPopupEx(id);
|
OpenPopupEx(id, popup_flags);
|
||||||
return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings);
|
return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui::BeginPopupContextWindow(const char* str_id, ImGuiMouseButton mouse_button, bool also_over_items)
|
bool ImGui::BeginPopupContextWindow(const char* str_id, ImGuiPopupFlags popup_flags)
|
||||||
{
|
{
|
||||||
|
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||||
if (!str_id)
|
if (!str_id)
|
||||||
str_id = "window_context";
|
str_id = "window_context";
|
||||||
ImGuiID id = GImGui->CurrentWindow->GetID(str_id);
|
ImGuiID id = window->GetID(str_id);
|
||||||
|
int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_);
|
||||||
if (IsMouseReleased(mouse_button) && IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
|
if (IsMouseReleased(mouse_button) && IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
|
||||||
if (also_over_items || !IsAnyItemHovered())
|
if (!(popup_flags & ImGuiPopupFlags_NoOpenOverItems) || !IsAnyItemHovered())
|
||||||
OpenPopupEx(id);
|
OpenPopupEx(id, popup_flags);
|
||||||
return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings);
|
return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui::BeginPopupContextVoid(const char* str_id, ImGuiMouseButton mouse_button)
|
bool ImGui::BeginPopupContextVoid(const char* str_id, ImGuiPopupFlags popup_flags)
|
||||||
{
|
{
|
||||||
|
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||||
if (!str_id)
|
if (!str_id)
|
||||||
str_id = "void_context";
|
str_id = "void_context";
|
||||||
ImGuiID id = GImGui->CurrentWindow->GetID(str_id);
|
ImGuiID id = window->GetID(str_id);
|
||||||
|
int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_);
|
||||||
if (IsMouseReleased(mouse_button) && !IsWindowHovered(ImGuiHoveredFlags_AnyWindow))
|
if (IsMouseReleased(mouse_button) && !IsWindowHovered(ImGuiHoveredFlags_AnyWindow))
|
||||||
OpenPopupEx(id);
|
if (GetTopMostPopupModal() == NULL)
|
||||||
|
OpenPopupEx(id, popup_flags);
|
||||||
return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings);
|
return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15420,7 +15406,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|||||||
|
|
||||||
ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL;
|
ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL;
|
||||||
char buf[300];
|
char buf[300];
|
||||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "DrawCmd: %4d triangles, Tex 0x%p, ClipRect (%4.0f,%4.0f)-(%4.0f,%4.0f)",
|
ImFormatString(buf, IM_ARRAYSIZE(buf), "DrawCmd:%5d triangles, Tex 0x%p, ClipRect (%4.0f,%4.0f)-(%4.0f,%4.0f)",
|
||||||
pcmd->ElemCount / 3, (void*)(intptr_t)pcmd->TextureId,
|
pcmd->ElemCount / 3, (void*)(intptr_t)pcmd->TextureId,
|
||||||
pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w);
|
pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w);
|
||||||
bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "%s", buf);
|
bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "%s", buf);
|
||||||
|
160
imgui/imgui.h
160
imgui/imgui.h
@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.77 WIP
|
// dear imgui, v1.77
|
||||||
// (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.77 WIP"
|
#define IMGUI_VERSION "1.77"
|
||||||
#define IMGUI_VERSION_NUM 17601
|
#define IMGUI_VERSION_NUM 17701
|
||||||
#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
|
||||||
@ -88,8 +88,8 @@ Index of this file:
|
|||||||
#define IM_FMTARGS(FMT)
|
#define IM_FMTARGS(FMT)
|
||||||
#define IM_FMTLIST(FMT)
|
#define IM_FMTLIST(FMT)
|
||||||
#endif
|
#endif
|
||||||
#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*_ARR))) // Size of a static C-style array. Don't use on pointers!
|
#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers!
|
||||||
#define IM_UNUSED(_VAR) ((void)_VAR) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds.
|
#define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds.
|
||||||
#if (__cplusplus >= 201100)
|
#if (__cplusplus >= 201100)
|
||||||
#define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER) // Offset of _MEMBER within _TYPE. Standardized as offsetof() in C++11
|
#define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER) // Offset of _MEMBER within _TYPE. Standardized as offsetof() in C++11
|
||||||
#else
|
#else
|
||||||
@ -169,6 +169,7 @@ typedef int ImGuiFocusedFlags; // -> enum ImGuiFocusedFlags_ // Flags: f
|
|||||||
typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc.
|
typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc.
|
||||||
typedef int ImGuiInputTextFlags; // -> enum ImGuiInputTextFlags_ // Flags: for InputText(), InputTextMultiline()
|
typedef int ImGuiInputTextFlags; // -> enum ImGuiInputTextFlags_ // Flags: for InputText(), InputTextMultiline()
|
||||||
typedef int ImGuiKeyModFlags; // -> enum ImGuiKeyModFlags_ // Flags: for io.KeyMods (Ctrl/Shift/Alt/Super)
|
typedef int ImGuiKeyModFlags; // -> enum ImGuiKeyModFlags_ // Flags: for io.KeyMods (Ctrl/Shift/Alt/Super)
|
||||||
|
typedef int ImGuiPopupFlags; // -> enum ImGuiPopupFlags_ // Flags: for OpenPopup*(), BeginPopupContext*(), IsPopupOpen()
|
||||||
typedef int ImGuiSelectableFlags; // -> enum ImGuiSelectableFlags_ // Flags: for Selectable()
|
typedef int ImGuiSelectableFlags; // -> enum ImGuiSelectableFlags_ // Flags: for Selectable()
|
||||||
typedef int ImGuiTabBarFlags; // -> enum ImGuiTabBarFlags_ // Flags: for BeginTabBar()
|
typedef int ImGuiTabBarFlags; // -> enum ImGuiTabBarFlags_ // Flags: for BeginTabBar()
|
||||||
typedef int ImGuiTabItemFlags; // -> enum ImGuiTabItemFlags_ // Flags: for BeginTabItem()
|
typedef int ImGuiTabItemFlags; // -> enum ImGuiTabItemFlags_ // Flags: for BeginTabItem()
|
||||||
@ -277,9 +278,10 @@ namespace ImGui
|
|||||||
|
|
||||||
// Windows
|
// Windows
|
||||||
// - Begin() = push window to the stack and start appending to it. End() = pop window from the stack.
|
// - Begin() = push window to the stack and start appending to it. End() = pop window from the stack.
|
||||||
// - You may append multiple times to the same window during the same frame.
|
|
||||||
// - Passing 'bool* p_open != NULL' shows a window-closing widget in the upper-right corner of the window,
|
// - Passing 'bool* p_open != NULL' shows a window-closing widget in the upper-right corner of the window,
|
||||||
// which clicking will set the boolean to false when clicked.
|
// which clicking will set the boolean to false when clicked.
|
||||||
|
// - You may append multiple times to the same window during the same frame by calling Begin()/End() pairs multiple times.
|
||||||
|
// Some information such as 'flags' or 'p_open' will only be considered by the first call to Begin().
|
||||||
// - Begin() return false to indicate the window is collapsed or fully clipped, so you may early out and omit submitting
|
// - Begin() return false to indicate the window is collapsed or fully clipped, so you may early out and omit submitting
|
||||||
// anything to the window. Always call a matching End() for each Begin() call, regardless of its return value!
|
// anything to the window. Always call a matching End() for each Begin() call, regardless of its return value!
|
||||||
// [Important: due to legacy reason, this is inconsistent with most other functions such as BeginMenu/EndMenu,
|
// [Important: due to legacy reason, this is inconsistent with most other functions such as BeginMenu/EndMenu,
|
||||||
@ -602,27 +604,41 @@ namespace ImGui
|
|||||||
IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1);
|
IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1);
|
||||||
|
|
||||||
// Popups, Modals
|
// Popups, Modals
|
||||||
// The properties of popups windows are:
|
// - They block normal mouse hovering detection (and therefore most mouse interactions) behind them.
|
||||||
// - They block normal mouse hovering detection outside them. (*1)
|
// - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE.
|
||||||
// - Unless modal, they can be closed by clicking anywhere outside them, or by pressing ESCAPE.
|
// - Their visibility state (~bool) is held internally instead of being held by the programmer as we are used to with regular Begin*() calls.
|
||||||
// Because hovering detection is disabled outside the popup, when clicking outside the click will not be seen by underlying widgets! (*1)
|
// - The 3 properties above are related: we need to retain popup visibility state in the library because popups may be closed as any time.
|
||||||
// - Their visibility state (~bool) is held internally by Dear ImGui instead of being held by the programmer as we are used to with regular Begin() calls.
|
// - You can bypass the hovering restriction by using ImGuiHoveredFlags_AllowWhenBlockedByPopup when calling IsItemHovered() or IsWindowHovered().
|
||||||
// User can manipulate the visibility state by calling OpenPopup(), CloseCurrentPopup() etc.
|
// - IMPORTANT: Popup identifiers are relative to the current ID stack, so OpenPopup and BeginPopup generally needs to be at the same level of the stack.
|
||||||
// - We default to use the right mouse (ImGuiMouseButton_Right=1) for the Popup Context functions.
|
// This is sometimes leading to confusing mistakes. May rework this in the future.
|
||||||
// Those three properties are connected: we need to retain popup visibility state in the library because popups may be closed as any time.
|
// Popups: begin/end functions
|
||||||
// (*1) You can bypass that restriction and detect hovering even when normally blocked by a popup.
|
// - BeginPopup(): query popup state, if open start appending into the window. Call EndPopup() afterwards. ImGuiWindowFlags are forwarded to the window.
|
||||||
// To do this use the ImGuiHoveredFlags_AllowWhenBlockedByPopup when calling IsItemHovered() or IsWindowHovered().
|
// - BeginPopupModal(): block every interactions behind the window, cannot be closed by user, add a dimming background, has a title bar.
|
||||||
// This is what BeginPopupContextItem() and BeginPopupContextWindow() are doing already, allowing a right-click to reopen another popups without losing the click.
|
IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it.
|
||||||
IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!). popups are closed when user click outside, or if CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. By default, Selectable()/MenuItem() are calling CloseCurrentPopup(). Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level).
|
IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // return true if the modal is open, and you can start outputting to it.
|
||||||
IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returns true!
|
|
||||||
IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiMouseButton mouse_button = 1); // helper to open and begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp!
|
|
||||||
IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, ImGuiMouseButton mouse_button = 1, bool also_over_items = true); // helper to open and begin popup when clicked on current window.
|
|
||||||
IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiMouseButton mouse_button = 1); // helper to open and begin popup when clicked in void (where there are no imgui windows).
|
|
||||||
IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // modal dialog (regular window with title bar, block interactions behind the modal window, can't close the modal window by clicking outside)
|
|
||||||
IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true!
|
IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true!
|
||||||
IMGUI_API bool OpenPopupOnItemClick(const char* str_id = NULL, ImGuiMouseButton mouse_button = 1); // helper to open popup when clicked on last item (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors). return true when just opened.
|
// Popups: open/close functions
|
||||||
IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open at the current begin-ed level of the popup stack.
|
// - OpenPopup(): set popup state to open. ImGuiPopupFlags are available for opening options.
|
||||||
IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup.
|
// - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE.
|
||||||
|
// - CloseCurrentPopup(): use inside the BeginPopup()/EndPopup() scope to close manually.
|
||||||
|
// - CloseCurrentPopup() is called by default by Selectable()/MenuItem() when activated (FIXME: need some options).
|
||||||
|
// - Use ImGuiPopupFlags_NoOpenOverExistingPopup to avoid opening a popup if there's already one at the same level. This is equivalent to e.g. testing for !IsAnyPopupOpen() prior to OpenPopup().
|
||||||
|
IMGUI_API void OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags = 0); // call to mark popup as open (don't call every frame!).
|
||||||
|
IMGUI_API bool OpenPopupContextItem(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // helper to open popup when clicked on last item. return true when just opened. (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors)
|
||||||
|
IMGUI_API void CloseCurrentPopup(); // manually close the popup we have begin-ed into.
|
||||||
|
// Popups: open+begin combined functions helpers
|
||||||
|
// - Helpers to do OpenPopup+BeginPopup where the Open action is triggered by e.g. hovering an item and right-clicking.
|
||||||
|
// - They are convenient to easily create context menus, hence the name.
|
||||||
|
// - IMPORTANT: Notice that BeginPopupContextXXX takes ImGuiPopupFlags just like OpenPopup() and unlike BeginPopup(). For full consistency, we may add ImGuiWindowFlags to the BeginPopupContextXXX functions in the future.
|
||||||
|
// - We exceptionally default their flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter. Passing a mouse button to ImGuiPopupFlags is guaranteed to be legal.
|
||||||
|
IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp!
|
||||||
|
IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1);// open+begin popup when clicked on current window.
|
||||||
|
IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked in void (where there are no windows).
|
||||||
|
// Popups: test function
|
||||||
|
// - IsPopupOpen(): return true if the popup is open at the current BeginPopup() level of the popup stack.
|
||||||
|
// - IsPopupOpen() with ImGuiPopupFlags_AnyPopupId: return true if any popup is open at the current BeginPopup() level of the popup stack.
|
||||||
|
// - IsPopupOpen() with ImGuiPopupFlags_AnyPopupId + ImGuiPopupFlags_AnyPopupLevel: return true if any popup is open.
|
||||||
|
IMGUI_API bool IsPopupOpen(const char* str_id, ImGuiPopupFlags flags = 0); // return true if the popup is open.
|
||||||
|
|
||||||
// Columns
|
// Columns
|
||||||
// - You can also use SameLine(pos_x) to mimic simplified columns.
|
// - You can also use SameLine(pos_x) to mimic simplified columns.
|
||||||
@ -901,6 +917,26 @@ enum ImGuiTreeNodeFlags_
|
|||||||
ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog
|
ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Flags for OpenPopup*(), BeginPopupContext*(), IsPopupOpen() functions.
|
||||||
|
// - To be backward compatible with older API which took an 'int mouse_button = 1' argument, we need to treat
|
||||||
|
// 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.
|
||||||
|
enum ImGuiPopupFlags_
|
||||||
|
{
|
||||||
|
ImGuiPopupFlags_None = 0,
|
||||||
|
ImGuiPopupFlags_MouseButtonLeft = 0, // For BeginPopupContext*(): open on Left Mouse release. Guaranted to always be == 0 (same as ImGuiMouseButton_Left)
|
||||||
|
ImGuiPopupFlags_MouseButtonRight = 1, // For BeginPopupContext*(): open on Right Mouse release. Guaranted to always be == 1 (same as ImGuiMouseButton_Right)
|
||||||
|
ImGuiPopupFlags_MouseButtonMiddle = 2, // For BeginPopupContext*(): open on Middle Mouse release. Guaranted to always be == 2 (same as ImGuiMouseButton_Middle)
|
||||||
|
ImGuiPopupFlags_MouseButtonMask_ = 0x1F,
|
||||||
|
ImGuiPopupFlags_MouseButtonDefault_ = 1,
|
||||||
|
ImGuiPopupFlags_NoOpenOverExistingPopup = 1 << 5, // For OpenPopup*(), BeginPopupContext*(): don't open if there's already a popup at the same level of the popup stack
|
||||||
|
ImGuiPopupFlags_NoOpenOverItems = 1 << 6, // For BeginPopupContextWindow(): don't return true when hovering items, only when hovering empty space
|
||||||
|
ImGuiPopupFlags_AnyPopupId = 1 << 7, // For IsPopupOpen(): ignore the ImGuiID parameter and test for any popup.
|
||||||
|
ImGuiPopupFlags_AnyPopupLevel = 1 << 8, // For IsPopupOpen(): search/test at any level of the popup stack (default test in the current level)
|
||||||
|
ImGuiPopupFlags_AnyPopup = ImGuiPopupFlags_AnyPopupId | ImGuiPopupFlags_AnyPopupLevel
|
||||||
|
};
|
||||||
|
|
||||||
// Flags for ImGui::Selectable()
|
// Flags for ImGui::Selectable()
|
||||||
enum ImGuiSelectableFlags_
|
enum ImGuiSelectableFlags_
|
||||||
{
|
{
|
||||||
@ -949,7 +985,8 @@ enum ImGuiTabItemFlags_
|
|||||||
ImGuiTabItemFlags_UnsavedDocument = 1 << 0, // Append '*' to title without affecting the ID, as a convenience to avoid using the ### operator. Also: tab is selected on closure and closure is deferred by one frame to allow code to undo it without flicker.
|
ImGuiTabItemFlags_UnsavedDocument = 1 << 0, // Append '*' to title without affecting the ID, as a convenience to avoid using the ### operator. Also: tab is selected on closure and closure is deferred by one frame to allow code to undo it without flicker.
|
||||||
ImGuiTabItemFlags_SetSelected = 1 << 1, // Trigger flag to programmatically make the tab selected when calling BeginTabItem()
|
ImGuiTabItemFlags_SetSelected = 1 << 1, // Trigger flag to programmatically make the tab selected when calling BeginTabItem()
|
||||||
ImGuiTabItemFlags_NoCloseWithMiddleMouseButton = 1 << 2, // Disable behavior of closing tabs (that are submitted with p_open != NULL) with middle mouse button. You can still repro this behavior on user's side with if (IsItemHovered() && IsMouseClicked(2)) *p_open = false.
|
ImGuiTabItemFlags_NoCloseWithMiddleMouseButton = 1 << 2, // Disable behavior of closing tabs (that are submitted with p_open != NULL) with middle mouse button. You can still repro this behavior on user's side with if (IsItemHovered() && IsMouseClicked(2)) *p_open = false.
|
||||||
ImGuiTabItemFlags_NoPushId = 1 << 3 // Don't call PushID(tab->ID)/PopID() on BeginTabItem()/EndTabItem()
|
ImGuiTabItemFlags_NoPushId = 1 << 3, // Don't call PushID(tab->ID)/PopID() on BeginTabItem()/EndTabItem()
|
||||||
|
ImGuiTabItemFlags_NoTooltip = 1 << 4 // Disable tooltip for the given tab
|
||||||
};
|
};
|
||||||
|
|
||||||
// Flags for ImGui::IsWindowFocused()
|
// Flags for ImGui::IsWindowFocused()
|
||||||
@ -1343,7 +1380,8 @@ enum ImGuiMouseCursor_
|
|||||||
// Important: Treat as a regular enum! Do NOT combine multiple values using binary operators! All the functions above treat 0 as a shortcut to ImGuiCond_Always.
|
// Important: Treat as a regular enum! Do NOT combine multiple values using binary operators! All the functions above treat 0 as a shortcut to ImGuiCond_Always.
|
||||||
enum ImGuiCond_
|
enum ImGuiCond_
|
||||||
{
|
{
|
||||||
ImGuiCond_Always = 1 << 0, // Set the variable
|
ImGuiCond_None = 0, // No condition (always set the variable), same as _Always
|
||||||
|
ImGuiCond_Always = 1 << 0, // No condition (always set the variable)
|
||||||
ImGuiCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call will succeed)
|
ImGuiCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call will succeed)
|
||||||
ImGuiCond_FirstUseEver = 1 << 2, // Set the variable if the object/window has no persistently saved data (no entry in .ini file)
|
ImGuiCond_FirstUseEver = 1 << 2, // Set the variable if the object/window has no persistently saved data (no entry in .ini file)
|
||||||
ImGuiCond_Appearing = 1 << 3 // Set the variable if the object/window is appearing after being hidden/inactive (or the first time)
|
ImGuiCond_Appearing = 1 << 3 // Set the variable if the object/window is appearing after being hidden/inactive (or the first time)
|
||||||
@ -1445,7 +1483,7 @@ struct ImGuiStyle
|
|||||||
{
|
{
|
||||||
float Alpha; // Global alpha applies to everything in Dear ImGui.
|
float Alpha; // Global alpha applies to everything in Dear ImGui.
|
||||||
ImVec2 WindowPadding; // Padding within a window.
|
ImVec2 WindowPadding; // Padding within a window.
|
||||||
float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows.
|
float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended.
|
||||||
float WindowBorderSize; // Thickness of border around windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly).
|
float WindowBorderSize; // Thickness of border around windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly).
|
||||||
ImVec2 WindowMinSize; // Minimum window size. This is a global setting. If you want to constraint individual windows, use SetNextWindowSizeConstraints().
|
ImVec2 WindowMinSize; // Minimum window size. This is a global setting. If you want to constraint individual windows, use SetNextWindowSizeConstraints().
|
||||||
ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered.
|
ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered.
|
||||||
@ -1629,6 +1667,7 @@ struct ImGuiIO
|
|||||||
float KeysDownDurationPrev[512]; // Previous duration the key has been down
|
float KeysDownDurationPrev[512]; // Previous duration the key has been down
|
||||||
float NavInputsDownDuration[ImGuiNavInput_COUNT];
|
float NavInputsDownDuration[ImGuiNavInput_COUNT];
|
||||||
float NavInputsDownDurationPrev[ImGuiNavInput_COUNT];
|
float NavInputsDownDurationPrev[ImGuiNavInput_COUNT];
|
||||||
|
float PenPressure; // Touch/Pen pressure (0.0f to 1.0f, should be >0.0f only when MouseDown[0] == true). Helper storage currently unused by Dear ImGui.
|
||||||
ImWchar16 InputQueueSurrogate; // For AddInputCharacterUTF16
|
ImWchar16 InputQueueSurrogate; // For AddInputCharacterUTF16
|
||||||
ImVector<ImWchar> InputQueueCharacters; // Queue of _characters_ input (obtained by platform back-end). Fill using AddInputCharacter() helper.
|
ImVector<ImWchar> InputQueueCharacters; // Queue of _characters_ input (obtained by platform back-end). Fill using AddInputCharacter() helper.
|
||||||
|
|
||||||
@ -1735,6 +1774,9 @@ struct ImGuiPayload
|
|||||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
namespace ImGui
|
namespace ImGui
|
||||||
{
|
{
|
||||||
|
// OBSOLETED in 1.77 (from June 2020)
|
||||||
|
static inline bool OpenPopupOnItemClick(const char* str_id = NULL, ImGuiMouseButton mb = 1) { return OpenPopupContextItem(str_id, mb); } // Passing a mouse button to ImGuiPopupFlags is legal
|
||||||
|
static inline bool BeginPopupContextWindow(const char* str_id, ImGuiMouseButton mb, bool over_items) { return BeginPopupContextWindow(str_id, mb | (over_items ? 0 : ImGuiPopupFlags_NoOpenOverItems)); }
|
||||||
// OBSOLETED in 1.72 (from July 2019)
|
// OBSOLETED in 1.72 (from July 2019)
|
||||||
static inline void TreeAdvanceToLabelPos() { SetCursorPosX(GetCursorPosX() + GetTreeNodeToLabelSpacing()); }
|
static inline void TreeAdvanceToLabelPos() { SetCursorPosX(GetCursorPosX() + GetTreeNodeToLabelSpacing()); }
|
||||||
// OBSOLETED in 1.71 (from June 2019)
|
// OBSOLETED in 1.71 (from June 2019)
|
||||||
@ -1755,7 +1797,6 @@ namespace ImGui
|
|||||||
// OBSOLETED in 1.60 (between Dec 2017 and Apr 2018)
|
// OBSOLETED in 1.60 (between Dec 2017 and Apr 2018)
|
||||||
static inline bool IsAnyWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_AnyWindow); }
|
static inline bool IsAnyWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_AnyWindow); }
|
||||||
static inline bool IsAnyWindowHovered() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); }
|
static inline bool IsAnyWindowHovered() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); }
|
||||||
static inline ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = 0.f) { IM_UNUSED(on_edge); IM_UNUSED(outward); IM_ASSERT(0); return pos; }
|
|
||||||
}
|
}
|
||||||
typedef ImGuiInputTextCallback ImGuiTextEditCallback; // OBSOLETED in 1.63 (from Aug 2018): made the names consistent
|
typedef ImGuiInputTextCallback ImGuiTextEditCallback; // OBSOLETED in 1.63 (from Aug 2018): made the names consistent
|
||||||
typedef ImGuiInputTextCallbackData ImGuiTextEditCallbackData;
|
typedef ImGuiInputTextCallbackData ImGuiTextEditCallbackData;
|
||||||
@ -1977,19 +2018,21 @@ typedef void (*ImDrawCallback)(const ImDrawList* parent_list, const ImDrawCmd* c
|
|||||||
#define ImDrawCallback_ResetRenderState (ImDrawCallback)(-1)
|
#define ImDrawCallback_ResetRenderState (ImDrawCallback)(-1)
|
||||||
|
|
||||||
// Typically, 1 command = 1 GPU draw call (unless command is a callback)
|
// Typically, 1 command = 1 GPU draw call (unless command is a callback)
|
||||||
// Pre 1.71 back-ends will typically ignore the VtxOffset/IdxOffset fields. When 'io.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset'
|
// - VtxOffset/IdxOffset: When 'io.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset' is enabled,
|
||||||
// is enabled, those fields allow us to render meshes larger than 64K vertices while keeping 16-bit indices.
|
// those fields allow us to render meshes larger than 64K vertices while keeping 16-bit indices.
|
||||||
|
// Pre-1.71 back-ends will typically ignore the VtxOffset/IdxOffset fields.
|
||||||
|
// - The ClipRect/TextureId/VtxOffset fields must be contiguous as we memcmp() them together (this is asserted for).
|
||||||
struct ImDrawCmd
|
struct ImDrawCmd
|
||||||
{
|
{
|
||||||
unsigned int ElemCount; // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[].
|
ImVec4 ClipRect; // 4*4 // Clipping rectangle (x1, y1, x2, y2). Subtract ImDrawData->DisplayPos to get clipping rectangle in "viewport" coordinates
|
||||||
ImVec4 ClipRect; // Clipping rectangle (x1, y1, x2, y2). Subtract ImDrawData->DisplayPos to get clipping rectangle in "viewport" coordinates
|
ImTextureID TextureId; // 4-8 // User-provided texture ID. Set by user in ImfontAtlas::SetTexID() for fonts or passed to Image*() functions. Ignore if never using images or multiple fonts atlas.
|
||||||
ImTextureID TextureId; // User-provided texture ID. Set by user in ImfontAtlas::SetTexID() for fonts or passed to Image*() functions. Ignore if never using images or multiple fonts atlas.
|
unsigned int VtxOffset; // 4 // Start offset in vertex buffer. ImGuiBackendFlags_RendererHasVtxOffset: always 0, otherwise may be >0 to support meshes larger than 64K vertices with 16-bit indices.
|
||||||
unsigned int VtxOffset; // Start offset in vertex buffer. Pre-1.71 or without ImGuiBackendFlags_RendererHasVtxOffset: always 0. With ImGuiBackendFlags_RendererHasVtxOffset: may be >0 to support meshes larger than 64K vertices with 16-bit indices.
|
unsigned int IdxOffset; // 4 // Start offset in index buffer. Always equal to sum of ElemCount drawn so far.
|
||||||
unsigned int IdxOffset; // Start offset in index buffer. Always equal to sum of ElemCount drawn so far.
|
unsigned int ElemCount; // 4 // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[].
|
||||||
ImDrawCallback UserCallback; // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally.
|
ImDrawCallback UserCallback; // 4-8 // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally.
|
||||||
void* UserCallbackData; // The draw callback code can access this.
|
void* UserCallbackData; // 4-8 // The draw callback code can access this.
|
||||||
|
|
||||||
ImDrawCmd() { ElemCount = 0; TextureId = (ImTextureID)NULL; VtxOffset = IdxOffset = 0; UserCallback = NULL; UserCallbackData = NULL; }
|
ImDrawCmd() { memset(this, 0, sizeof(*this)); } // Also ensure our padding fields are zeroed
|
||||||
};
|
};
|
||||||
|
|
||||||
// Vertex index, default to 16-bit
|
// Vertex index, default to 16-bit
|
||||||
@ -2080,18 +2123,19 @@ struct ImDrawList
|
|||||||
// [Internal, used while building lists]
|
// [Internal, used while building lists]
|
||||||
const ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context)
|
const ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context)
|
||||||
const char* _OwnerName; // Pointer to owner window's name for debugging
|
const char* _OwnerName; // Pointer to owner window's name for debugging
|
||||||
unsigned int _VtxCurrentOffset; // [Internal] Always 0 unless 'Flags & ImDrawListFlags_AllowVtxOffset'.
|
|
||||||
unsigned int _VtxCurrentIdx; // [Internal] Generally == VtxBuffer.Size unless we are past 64K vertices, in which case this gets reset to 0.
|
unsigned int _VtxCurrentIdx; // [Internal] Generally == VtxBuffer.Size unless we are past 64K vertices, in which case this gets reset to 0.
|
||||||
ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
|
ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
|
||||||
ImDrawIdx* _IdxWritePtr; // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
|
ImDrawIdx* _IdxWritePtr; // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
|
||||||
ImVector<ImVec4> _ClipRectStack; // [Internal]
|
ImVector<ImVec4> _ClipRectStack; // [Internal]
|
||||||
ImVector<ImTextureID> _TextureIdStack; // [Internal]
|
ImVector<ImTextureID> _TextureIdStack; // [Internal]
|
||||||
ImVector<ImVec2> _Path; // [Internal] current path building
|
ImVector<ImVec2> _Path; // [Internal] current path building
|
||||||
ImDrawListSplitter _Splitter; // [Internal] for channels api
|
ImDrawCmd _CmdHeader; // [Internal] Template of active commands. Fields should match those of CmdBuffer.back().
|
||||||
|
ImDrawListSplitter _Splitter; // [Internal] for channels api (note: prefer using your own persistent instance of ImDrawListSplitter!)
|
||||||
|
|
||||||
// If you want to create ImDrawList instances, pass them ImGui::GetDrawListSharedData() or create and use your own ImDrawListSharedData (so you can use ImDrawList without ImGui)
|
// If you want to create ImDrawList instances, pass them ImGui::GetDrawListSharedData() or create and use your own ImDrawListSharedData (so you can use ImDrawList without ImGui)
|
||||||
ImDrawList(const ImDrawListSharedData* shared_data) { _Data = shared_data; _OwnerName = NULL; Clear(); }
|
ImDrawList(const ImDrawListSharedData* shared_data) { _Data = shared_data; Flags = ImDrawListFlags_None; _VtxCurrentIdx = 0; _VtxWritePtr = NULL; _IdxWritePtr = NULL; _OwnerName = NULL; }
|
||||||
~ImDrawList() { ClearFreeMemory(); }
|
|
||||||
|
~ImDrawList() { _ClearFreeMemory(); }
|
||||||
IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
|
IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
|
||||||
IMGUI_API void PushClipRectFullScreen();
|
IMGUI_API void PushClipRectFullScreen();
|
||||||
IMGUI_API void PopClipRect();
|
IMGUI_API void PopClipRect();
|
||||||
@ -2151,16 +2195,15 @@ struct ImDrawList
|
|||||||
// - Use to split render into layers. By switching channels to can render out-of-order (e.g. submit FG primitives before BG primitives)
|
// - Use to split render into layers. By switching channels to can render out-of-order (e.g. submit FG primitives before BG primitives)
|
||||||
// - Use to minimize draw calls (e.g. if going back-and-forth between multiple clipping rectangles, prefer to append into separate channels then merge at the end)
|
// - Use to minimize draw calls (e.g. if going back-and-forth between multiple clipping rectangles, prefer to append into separate channels then merge at the end)
|
||||||
// - FIXME-OBSOLETE: This API shouldn't have been in ImDrawList in the first place!
|
// - FIXME-OBSOLETE: This API shouldn't have been in ImDrawList in the first place!
|
||||||
// Prefer using your own persistent copy of ImDrawListSplitter as you can stack them.
|
// Prefer using your own persistent instance of ImDrawListSplitter as you can stack them.
|
||||||
// Using the ImDrawList::ChannelsXXXX you cannot stack a split over another.
|
// Using the ImDrawList::ChannelsXXXX you cannot stack a split over another.
|
||||||
inline void ChannelsSplit(int count) { _Splitter.Split(this, count); }
|
inline void ChannelsSplit(int count) { _Splitter.Split(this, count); }
|
||||||
inline void ChannelsMerge() { _Splitter.Merge(this); }
|
inline void ChannelsMerge() { _Splitter.Merge(this); }
|
||||||
inline void ChannelsSetCurrent(int n) { _Splitter.SetCurrentChannel(this, n); }
|
inline void ChannelsSetCurrent(int n) { _Splitter.SetCurrentChannel(this, n); }
|
||||||
|
|
||||||
// Internal helpers
|
// Advanced: Primitives allocations
|
||||||
// NB: all primitives needs to be reserved via PrimReserve() beforehand!
|
// - We render triangles (three vertices)
|
||||||
IMGUI_API void Clear();
|
// - All primitives needs to be reserved via PrimReserve() beforehand.
|
||||||
IMGUI_API void ClearFreeMemory();
|
|
||||||
IMGUI_API void PrimReserve(int idx_count, int vtx_count);
|
IMGUI_API void PrimReserve(int idx_count, int vtx_count);
|
||||||
IMGUI_API void PrimUnreserve(int idx_count, int vtx_count);
|
IMGUI_API void PrimUnreserve(int idx_count, int vtx_count);
|
||||||
IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col); // Axis aligned rectangle (composed of two triangles)
|
IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col); // Axis aligned rectangle (composed of two triangles)
|
||||||
@ -2168,9 +2211,15 @@ struct ImDrawList
|
|||||||
IMGUI_API void PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col);
|
IMGUI_API void PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col);
|
||||||
inline void PrimWriteVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { _VtxWritePtr->pos = pos; _VtxWritePtr->uv = uv; _VtxWritePtr->col = col; _VtxWritePtr++; _VtxCurrentIdx++; }
|
inline void PrimWriteVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { _VtxWritePtr->pos = pos; _VtxWritePtr->uv = uv; _VtxWritePtr->col = col; _VtxWritePtr++; _VtxCurrentIdx++; }
|
||||||
inline void PrimWriteIdx(ImDrawIdx idx) { *_IdxWritePtr = idx; _IdxWritePtr++; }
|
inline void PrimWriteIdx(ImDrawIdx idx) { *_IdxWritePtr = idx; _IdxWritePtr++; }
|
||||||
inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); }
|
inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); } // Write vertex with unique index
|
||||||
IMGUI_API void UpdateClipRect();
|
|
||||||
IMGUI_API void UpdateTextureID();
|
// [Internal helpers]
|
||||||
|
IMGUI_API void _ResetForNewFrame();
|
||||||
|
IMGUI_API void _ClearFreeMemory();
|
||||||
|
IMGUI_API void _PopUnusedDrawCmd();
|
||||||
|
IMGUI_API void _OnChangedClipRect();
|
||||||
|
IMGUI_API void _OnChangedTextureID();
|
||||||
|
IMGUI_API void _OnChangedVtxOffset();
|
||||||
};
|
};
|
||||||
|
|
||||||
// All draw data to render a Dear ImGui frame
|
// All draw data to render a Dear ImGui frame
|
||||||
@ -2341,7 +2390,7 @@ struct ImFontAtlas
|
|||||||
// After calling Build(), you can query the rectangle position and render your pixels.
|
// After calling Build(), you can query the rectangle position and render your pixels.
|
||||||
// You can also request your rectangles to be mapped as font glyph (given a font + Unicode point),
|
// You can also request your rectangles to be mapped as font glyph (given a font + Unicode point),
|
||||||
// so you can render e.g. custom colorful icons and use them as regular glyphs.
|
// so you can render e.g. custom colorful icons and use them as regular glyphs.
|
||||||
// Read docs/FONTS.txt for more details about using colorful icons.
|
// Read docs/FONTS.md for more details about using colorful icons.
|
||||||
// Note: this API may be redesigned later in order to support multi-monitor varying DPI settings.
|
// Note: this API may be redesigned later in order to support multi-monitor varying DPI settings.
|
||||||
IMGUI_API int AddCustomRectRegular(int width, int height);
|
IMGUI_API int AddCustomRectRegular(int width, int height);
|
||||||
IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0, 0));
|
IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0, 0));
|
||||||
@ -2552,7 +2601,7 @@ struct ImGuiPlatformIO
|
|||||||
struct ImGuiPlatformMonitor
|
struct ImGuiPlatformMonitor
|
||||||
{
|
{
|
||||||
ImVec2 MainPos, MainSize; // Coordinates of the area displayed on this monitor (Min = upper left, Max = bottom right)
|
ImVec2 MainPos, MainSize; // Coordinates of the area displayed on this monitor (Min = upper left, Max = bottom right)
|
||||||
ImVec2 WorkPos, WorkSize; // (Optional) Coordinates without task bars / side bars / menu bars. imgui uses this to avoid positioning popups/tooltips inside this region.
|
ImVec2 WorkPos, WorkSize; // Coordinates without task bars / side bars / menu bars. Used to avoid positioning popups/tooltips inside this region. If you don't have this info, please copy the value for MainPos/MainSize.
|
||||||
float DpiScale; // 1.0f = 96 DPI
|
float DpiScale; // 1.0f = 96 DPI
|
||||||
ImGuiPlatformMonitor() { MainPos = MainSize = WorkPos = WorkSize = ImVec2(0, 0); DpiScale = 1.0f; }
|
ImGuiPlatformMonitor() { MainPos = MainSize = WorkPos = WorkSize = ImVec2(0, 0); DpiScale = 1.0f; }
|
||||||
};
|
};
|
||||||
@ -2603,7 +2652,8 @@ struct ImGuiViewport
|
|||||||
ImGuiViewport() { ID = 0; Flags = 0; DpiScale = 0.0f; DrawData = NULL; ParentViewportId = 0; RendererUserData = PlatformUserData = PlatformHandle = PlatformHandleRaw = NULL; PlatformRequestMove = PlatformRequestResize = PlatformRequestClose = false; }
|
ImGuiViewport() { ID = 0; Flags = 0; DpiScale = 0.0f; DrawData = NULL; ParentViewportId = 0; RendererUserData = PlatformUserData = PlatformHandle = PlatformHandleRaw = NULL; PlatformRequestMove = PlatformRequestResize = PlatformRequestClose = false; }
|
||||||
~ImGuiViewport() { IM_ASSERT(PlatformUserData == NULL && RendererUserData == NULL); }
|
~ImGuiViewport() { IM_ASSERT(PlatformUserData == NULL && RendererUserData == NULL); }
|
||||||
|
|
||||||
// Access work-area rectangle
|
// Access work-area rectangle with GetWorkXXX functions (see comments above)
|
||||||
|
ImVec2 GetCenter() { return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); }
|
||||||
ImVec2 GetWorkPos() { return ImVec2(Pos.x + WorkOffsetMin.x, Pos.y + WorkOffsetMin.y); }
|
ImVec2 GetWorkPos() { return ImVec2(Pos.x + WorkOffsetMin.x, Pos.y + WorkOffsetMin.y); }
|
||||||
ImVec2 GetWorkSize() { return ImVec2(Size.x - WorkOffsetMin.x + WorkOffsetMax.x, Size.y - WorkOffsetMin.y + WorkOffsetMax.y); } // This not clamped
|
ImVec2 GetWorkSize() { return ImVec2(Size.x - WorkOffsetMin.x + WorkOffsetMax.x, Size.y - WorkOffsetMin.y + WorkOffsetMax.y); } // This not clamped
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.77 WIP
|
// dear imgui, v1.77
|
||||||
// (demo code)
|
// (demo code)
|
||||||
|
|
||||||
// Help:
|
// Help:
|
||||||
@ -80,25 +80,27 @@ Index of this file:
|
|||||||
#include <stdint.h> // intptr_t
|
#include <stdint.h> // intptr_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Visual Studio warnings
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
|
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Clang/GCC warnings with -Weverything
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
|
#if __has_warning("-Wunknown-warning-option")
|
||||||
|
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great!
|
||||||
|
#endif
|
||||||
|
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
|
||||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations" // warning: 'xx' is deprecated: The POSIX name for this.. // for strdup used in demo code (so user can copy & paste the code)
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations" // warning: 'xx' is deprecated: The POSIX name for this.. // for strdup used in demo code (so user can copy & paste the code)
|
||||||
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning: cast to 'void *' from smaller integer type
|
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning: cast to 'void *' from smaller integer type
|
||||||
#pragma clang diagnostic ignored "-Wformat-security" // warning: format string is not a string literal
|
#pragma clang diagnostic ignored "-Wformat-security" // warning: format string is not a string literal
|
||||||
#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
|
#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
|
||||||
#pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used // we define snprintf/vsnprintf on Windows so they are available, but not always used.
|
#pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used // we define snprintf/vsnprintf on Windows so they are available, but not always used.
|
||||||
#if __has_warning("-Wzero-as-null-pointer-constant")
|
|
||||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
|
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
|
||||||
#endif
|
|
||||||
#if __has_warning("-Wdouble-promotion")
|
|
||||||
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
|
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
|
||||||
#endif
|
|
||||||
#if __has_warning("-Wreserved-id-macro")
|
|
||||||
#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier
|
#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier
|
||||||
#endif
|
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||||
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
|
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
|
||||||
@ -154,7 +156,7 @@ static void ShowExampleAppCustomRendering(bool* p_open);
|
|||||||
static void ShowExampleMenuFile();
|
static void ShowExampleMenuFile();
|
||||||
|
|
||||||
// Helper to display a little (?) mark which shows a tooltip when hovered.
|
// Helper to display a little (?) mark which shows a tooltip when hovered.
|
||||||
// In your own code you may want to display an actual icon if you are using a merged icon fonts (see docs/FONTS.txt)
|
// In your own code you may want to display an actual icon if you are using a merged icon fonts (see docs/FONTS.md)
|
||||||
static void HelpMarker(const char* desc)
|
static void HelpMarker(const char* desc)
|
||||||
{
|
{
|
||||||
ImGui::TextDisabled("(?)");
|
ImGui::TextDisabled("(?)");
|
||||||
@ -915,7 +917,7 @@ static void ShowDemoWindowWidgets()
|
|||||||
if (ImGui::TreeNode("UTF-8 Text"))
|
if (ImGui::TreeNode("UTF-8 Text"))
|
||||||
{
|
{
|
||||||
// UTF-8 test with Japanese characters
|
// UTF-8 test with Japanese characters
|
||||||
// (Needs a suitable font? Try "Google Noto" or "Arial Unicode". See docs/FONTS.txt for details.)
|
// (Needs a suitable font? Try "Google Noto" or "Arial Unicode". See docs/FONTS.md for details.)
|
||||||
// - From C++11 you can use the u8"my text" syntax to encode literal strings as UTF-8
|
// - From C++11 you can use the u8"my text" syntax to encode literal strings as UTF-8
|
||||||
// - For earlier compiler, you may be able to encode your sources as UTF-8 (e.g. in Visual Studio, you
|
// - For earlier compiler, you may be able to encode your sources as UTF-8 (e.g. in Visual Studio, you
|
||||||
// can save your source files as 'UTF-8 without signature').
|
// can save your source files as 'UTF-8 without signature').
|
||||||
@ -927,7 +929,7 @@ static void ShowDemoWindowWidgets()
|
|||||||
ImGui::TextWrapped(
|
ImGui::TextWrapped(
|
||||||
"CJK text will only appears if the font was loaded with the appropriate CJK character ranges. "
|
"CJK text will only appears if the font was loaded with the appropriate CJK character ranges. "
|
||||||
"Call io.Font->AddFontFromFileTTF() manually to load extra character ranges. "
|
"Call io.Font->AddFontFromFileTTF() manually to load extra character ranges. "
|
||||||
"Read docs/FONTS.txt for details.");
|
"Read docs/FONTS.md for details.");
|
||||||
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); // Normally we would use u8"blah blah" with the proper characters directly in the string.
|
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); // Normally we would use u8"blah blah" with the proper characters directly in the string.
|
||||||
ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
|
ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
|
||||||
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
|
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
|
||||||
@ -2870,7 +2872,7 @@ static void ShowDemoWindowPopups()
|
|||||||
if (ImGui::TreeNode("Context menus"))
|
if (ImGui::TreeNode("Context menus"))
|
||||||
{
|
{
|
||||||
// BeginPopupContextItem() is a helper to provide common/simple popup behavior of essentially doing:
|
// BeginPopupContextItem() is a helper to provide common/simple popup behavior of essentially doing:
|
||||||
// if (IsItemHovered() && IsMouseReleased(0))
|
// if (IsItemHovered() && IsMouseReleased(ImGuiMouseButton_Right))
|
||||||
// OpenPopup(id);
|
// OpenPopup(id);
|
||||||
// return BeginPopup(id);
|
// return BeginPopup(id);
|
||||||
// For more advanced uses you may want to replicate and customize this code.
|
// For more advanced uses you may want to replicate and customize this code.
|
||||||
@ -2886,11 +2888,11 @@ static void ShowDemoWindowPopups()
|
|||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can also use OpenPopupOnItemClick() which is the same as BeginPopupContextItem() but without the
|
// We can also use OpenPopupContextItem() which is the same as BeginPopupContextItem() but without the
|
||||||
// Begin() call. So here we will make it that clicking on the text field with the right mouse button (1)
|
// Begin() call. So here we will make it that clicking on the text field with the right mouse button (1)
|
||||||
// will toggle the visibility of the popup above.
|
// will toggle the visibility of the popup above.
|
||||||
ImGui::Text("(You can also right-click me to open the same popup as above.)");
|
ImGui::Text("(You can also right-click me to open the same popup as above.)");
|
||||||
ImGui::OpenPopupOnItemClick("item context menu", 1);
|
ImGui::OpenPopupContextItem("item context menu", 1);
|
||||||
|
|
||||||
// When used after an item that has an ID (e.g.Button), we can skip providing an ID to BeginPopupContextItem().
|
// When used after an item that has an ID (e.g.Button), we can skip providing an ID to BeginPopupContextItem().
|
||||||
// BeginPopupContextItem() will use the last item ID as the popup ID.
|
// BeginPopupContextItem() will use the last item ID as the popup ID.
|
||||||
@ -2920,6 +2922,13 @@ static void ShowDemoWindowPopups()
|
|||||||
if (ImGui::Button("Delete.."))
|
if (ImGui::Button("Delete.."))
|
||||||
ImGui::OpenPopup("Delete?");
|
ImGui::OpenPopup("Delete?");
|
||||||
|
|
||||||
|
// Always center this window when appearing
|
||||||
|
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||||
|
//ImVec2 parent_pos = ImGui::GetWindowPos();
|
||||||
|
//ImVec2 parent_size = ImGui::GetWindowSize();
|
||||||
|
//ImVec2 center(parent_pos.x + parent_size.x * 0.5f, parent_pos.y + parent_size.y * 0.5f);
|
||||||
|
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||||
|
|
||||||
if (ImGui::BeginPopupModal("Delete?", NULL, ImGuiWindowFlags_AlwaysAutoResize))
|
if (ImGui::BeginPopupModal("Delete?", NULL, ImGuiWindowFlags_AlwaysAutoResize))
|
||||||
{
|
{
|
||||||
ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n");
|
ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n");
|
||||||
@ -3616,7 +3625,7 @@ void ImGui::ShowFontSelector(const char* label)
|
|||||||
HelpMarker(
|
HelpMarker(
|
||||||
"- Load additional fonts with io.Fonts->AddFontFromFileTTF().\n"
|
"- Load additional fonts with io.Fonts->AddFontFromFileTTF().\n"
|
||||||
"- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\n"
|
"- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\n"
|
||||||
"- Read FAQ and docs/FONTS.txt for more details.\n"
|
"- Read FAQ and docs/FONTS.md for more details.\n"
|
||||||
"- If you need to add/remove fonts at runtime (e.g. for DPI change), do it before calling NewFrame().");
|
"- If you need to add/remove fonts at runtime (e.g. for DPI change), do it before calling NewFrame().");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3844,7 +3853,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
|||||||
{
|
{
|
||||||
// Tips: in a real user application, you may want to merge and use an icon font into the main font,
|
// Tips: in a real user application, you may want to merge and use an icon font into the main font,
|
||||||
// so instead of "Save"/"Revert" you'd use icons!
|
// so instead of "Save"/"Revert" you'd use icons!
|
||||||
// Read the FAQ and docs/FONTS.txt about using icon fonts. It's really easy and super convenient!
|
// Read the FAQ and docs/FONTS.md about using icon fonts. It's really easy and super convenient!
|
||||||
ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); if (ImGui::Button("Save")) { ref->Colors[i] = style.Colors[i]; }
|
ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); if (ImGui::Button("Save")) { ref->Colors[i] = style.Colors[i]; }
|
||||||
ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); if (ImGui::Button("Revert")) { style.Colors[i] = ref->Colors[i]; }
|
ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); if (ImGui::Button("Revert")) { style.Colors[i] = ref->Colors[i]; }
|
||||||
}
|
}
|
||||||
@ -3862,7 +3871,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
|||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImFontAtlas* atlas = io.Fonts;
|
ImFontAtlas* atlas = io.Fonts;
|
||||||
HelpMarker("Read FAQ and docs/FONTS.txt for details on font loading.");
|
HelpMarker("Read FAQ and docs/FONTS.md for details on font loading.");
|
||||||
ImGui::PushItemWidth(120);
|
ImGui::PushItemWidth(120);
|
||||||
for (int i = 0; i < atlas->Fonts.Size; i++)
|
for (int i = 0; i < atlas->Fonts.Size; i++)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.77 WIP
|
// dear imgui, v1.77
|
||||||
// (drawing and font code)
|
// (drawing and font code)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -57,22 +57,19 @@ Index of this file:
|
|||||||
|
|
||||||
// Clang/GCC warnings with -Weverything
|
// Clang/GCC warnings with -Weverything
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
|
#if __has_warning("-Wunknown-warning-option")
|
||||||
|
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great!
|
||||||
|
#endif
|
||||||
|
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
|
||||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||||||
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants ok.
|
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants ok.
|
||||||
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is.
|
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is.
|
||||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness //
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||||
#if __has_warning("-Wzero-as-null-pointer-constant")
|
|
||||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
|
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
|
||||||
#endif
|
#pragma clang diagnostic ignored "-Wcomma" // warning: possible misuse of comma operator here
|
||||||
#if __has_warning("-Wcomma")
|
#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier
|
||||||
#pragma clang diagnostic ignored "-Wcomma" // warning : possible misuse of comma operator here //
|
|
||||||
#endif
|
|
||||||
#if __has_warning("-Wreserved-id-macro")
|
|
||||||
#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier //
|
|
||||||
#endif
|
|
||||||
#if __has_warning("-Wdouble-promotion")
|
|
||||||
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
|
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
|
||||||
#endif
|
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||||
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
|
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
|
||||||
@ -108,7 +105,7 @@ namespace IMGUI_STB_NAMESPACE
|
|||||||
#pragma clang diagnostic ignored "-Wunused-function"
|
#pragma clang diagnostic ignored "-Wunused-function"
|
||||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||||
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
|
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
|
||||||
#pragma clang diagnostic ignored "-Wcast-qual" // warning : cast from 'const xxxx *' to 'xxx *' drops const qualifier //
|
#pragma clang diagnostic ignored "-Wcast-qual" // warning: cast from 'const xxxx *' to 'xxx *' drops const qualifier
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
@ -382,13 +379,20 @@ void ImDrawListSharedData::SetCircleSegmentMaxError(float max_error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::Clear()
|
// Initialize before use in a new frame. We always have a command ready in the buffer.
|
||||||
|
void ImDrawList::_ResetForNewFrame()
|
||||||
{
|
{
|
||||||
|
// Verify that the ImDrawCmd fields we want to memcmp() are contiguous in memory.
|
||||||
|
// (those should be IM_STATIC_ASSERT() in theory but with our pre C++11 setup the whole check doesn't compile with GCC)
|
||||||
|
IM_ASSERT(IM_OFFSETOF(ImDrawCmd, ClipRect) == 0);
|
||||||
|
IM_ASSERT(IM_OFFSETOF(ImDrawCmd, TextureId) == sizeof(ImVec4));
|
||||||
|
IM_ASSERT(IM_OFFSETOF(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureID));
|
||||||
|
|
||||||
CmdBuffer.resize(0);
|
CmdBuffer.resize(0);
|
||||||
IdxBuffer.resize(0);
|
IdxBuffer.resize(0);
|
||||||
VtxBuffer.resize(0);
|
VtxBuffer.resize(0);
|
||||||
Flags = _Data ? _Data->InitialFlags : ImDrawListFlags_None;
|
Flags = _Data->InitialFlags;
|
||||||
_VtxCurrentOffset = 0;
|
memset(&_CmdHeader, 0, sizeof(_CmdHeader));
|
||||||
_VtxCurrentIdx = 0;
|
_VtxCurrentIdx = 0;
|
||||||
_VtxWritePtr = NULL;
|
_VtxWritePtr = NULL;
|
||||||
_IdxWritePtr = NULL;
|
_IdxWritePtr = NULL;
|
||||||
@ -396,13 +400,15 @@ void ImDrawList::Clear()
|
|||||||
_TextureIdStack.resize(0);
|
_TextureIdStack.resize(0);
|
||||||
_Path.resize(0);
|
_Path.resize(0);
|
||||||
_Splitter.Clear();
|
_Splitter.Clear();
|
||||||
|
CmdBuffer.push_back(ImDrawCmd());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::ClearFreeMemory()
|
void ImDrawList::_ClearFreeMemory()
|
||||||
{
|
{
|
||||||
CmdBuffer.clear();
|
CmdBuffer.clear();
|
||||||
IdxBuffer.clear();
|
IdxBuffer.clear();
|
||||||
VtxBuffer.clear();
|
VtxBuffer.clear();
|
||||||
|
Flags = ImDrawListFlags_None;
|
||||||
_VtxCurrentIdx = 0;
|
_VtxCurrentIdx = 0;
|
||||||
_VtxWritePtr = NULL;
|
_VtxWritePtr = NULL;
|
||||||
_IdxWritePtr = NULL;
|
_IdxWritePtr = NULL;
|
||||||
@ -422,86 +428,117 @@ ImDrawList* ImDrawList::CloneOutput() const
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug builds
|
|
||||||
#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : _Data->ClipRectFullscreen)
|
|
||||||
#define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : (ImTextureID)NULL)
|
|
||||||
|
|
||||||
void ImDrawList::AddDrawCmd()
|
void ImDrawList::AddDrawCmd()
|
||||||
{
|
{
|
||||||
ImDrawCmd draw_cmd;
|
ImDrawCmd draw_cmd;
|
||||||
draw_cmd.ClipRect = GetCurrentClipRect();
|
draw_cmd.ClipRect = _CmdHeader.ClipRect; // Same as calling ImDrawCmd_HeaderCopy()
|
||||||
draw_cmd.TextureId = GetCurrentTextureId();
|
draw_cmd.TextureId = _CmdHeader.TextureId;
|
||||||
draw_cmd.VtxOffset = _VtxCurrentOffset;
|
draw_cmd.VtxOffset = _CmdHeader.VtxOffset;
|
||||||
draw_cmd.IdxOffset = IdxBuffer.Size;
|
draw_cmd.IdxOffset = IdxBuffer.Size;
|
||||||
|
|
||||||
IM_ASSERT(draw_cmd.ClipRect.x <= draw_cmd.ClipRect.z && draw_cmd.ClipRect.y <= draw_cmd.ClipRect.w);
|
IM_ASSERT(draw_cmd.ClipRect.x <= draw_cmd.ClipRect.z && draw_cmd.ClipRect.y <= draw_cmd.ClipRect.w);
|
||||||
CmdBuffer.push_back(draw_cmd);
|
CmdBuffer.push_back(draw_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pop trailing draw command (used before merging or presenting to user)
|
||||||
|
// Note that this leaves the ImDrawList in a state unfit for further commands, as most code assume that CmdBuffer.Size > 0 && CmdBuffer.back().UserCallback == NULL
|
||||||
|
void ImDrawList::_PopUnusedDrawCmd()
|
||||||
|
{
|
||||||
|
if (CmdBuffer.Size == 0)
|
||||||
|
return;
|
||||||
|
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||||
|
if (curr_cmd->ElemCount == 0 && curr_cmd->UserCallback == NULL)
|
||||||
|
CmdBuffer.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
|
void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
|
||||||
{
|
{
|
||||||
ImDrawCmd* current_cmd = CmdBuffer.Size ? &CmdBuffer.back() : NULL;
|
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||||
if (!current_cmd || current_cmd->ElemCount != 0 || current_cmd->UserCallback != NULL)
|
IM_ASSERT(curr_cmd->UserCallback == NULL);
|
||||||
|
if (curr_cmd->ElemCount != 0)
|
||||||
{
|
{
|
||||||
AddDrawCmd();
|
AddDrawCmd();
|
||||||
current_cmd = &CmdBuffer.back();
|
curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||||
}
|
}
|
||||||
current_cmd->UserCallback = callback;
|
curr_cmd->UserCallback = callback;
|
||||||
current_cmd->UserCallbackData = callback_data;
|
curr_cmd->UserCallbackData = callback_data;
|
||||||
|
|
||||||
AddDrawCmd(); // Force a new command after us (see comment below)
|
AddDrawCmd(); // Force a new command after us (see comment below)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compare ClipRect, TextureId and VtxOffset with a single memcmp()
|
||||||
|
#define ImDrawCmd_HeaderSize (IM_OFFSETOF(ImDrawCmd, VtxOffset) + sizeof(unsigned int))
|
||||||
|
#define ImDrawCmd_HeaderCompare(CMD_LHS, CMD_RHS) (memcmp(CMD_LHS, CMD_RHS, ImDrawCmd_HeaderSize)) // Compare ClipRect, TextureId, VtxOffset
|
||||||
|
#define ImDrawCmd_HeaderCopy(CMD_DST, CMD_SRC) (memcpy(CMD_DST, CMD_SRC, ImDrawCmd_HeaderSize)) // Copy ClipRect, TextureId, VtxOffset
|
||||||
|
|
||||||
// Our scheme may appears a bit unusual, basically we want the most-common calls AddLine AddRect etc. to not have to perform any check so we always have a command ready in the stack.
|
// Our scheme may appears a bit unusual, basically we want the most-common calls AddLine AddRect etc. to not have to perform any check so we always have a command ready in the stack.
|
||||||
// The cost of figuring out if a new command has to be added or if we can merge is paid in those Update** functions only.
|
// The cost of figuring out if a new command has to be added or if we can merge is paid in those Update** functions only.
|
||||||
void ImDrawList::UpdateClipRect()
|
void ImDrawList::_OnChangedClipRect()
|
||||||
{
|
{
|
||||||
// If current command is used with different settings we need to add a new command
|
// If current command is used with different settings we need to add a new command
|
||||||
const ImVec4 curr_clip_rect = GetCurrentClipRect();
|
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||||
ImDrawCmd* curr_cmd = CmdBuffer.Size > 0 ? &CmdBuffer.Data[CmdBuffer.Size-1] : NULL;
|
if (curr_cmd->ElemCount != 0 && memcmp(&curr_cmd->ClipRect, &_CmdHeader.ClipRect, sizeof(ImVec4)) != 0)
|
||||||
if (!curr_cmd || (curr_cmd->ElemCount != 0 && memcmp(&curr_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) != 0) || curr_cmd->UserCallback != NULL)
|
|
||||||
{
|
{
|
||||||
AddDrawCmd();
|
AddDrawCmd();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
IM_ASSERT(curr_cmd->UserCallback == NULL);
|
||||||
|
|
||||||
// Try to merge with previous command if it matches, else use current command
|
// Try to merge with previous command if it matches, else use current command
|
||||||
ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL;
|
ImDrawCmd* prev_cmd = curr_cmd - 1;
|
||||||
if (curr_cmd->ElemCount == 0 && prev_cmd && memcmp(&prev_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) == 0 && prev_cmd->TextureId == GetCurrentTextureId() && prev_cmd->UserCallback == NULL)
|
if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1 && ImDrawCmd_HeaderCompare(&_CmdHeader, prev_cmd) == 0 && prev_cmd->UserCallback == NULL)
|
||||||
|
{
|
||||||
CmdBuffer.pop_back();
|
CmdBuffer.pop_back();
|
||||||
else
|
return;
|
||||||
curr_cmd->ClipRect = curr_clip_rect;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::UpdateTextureID()
|
curr_cmd->ClipRect = _CmdHeader.ClipRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImDrawList::_OnChangedTextureID()
|
||||||
{
|
{
|
||||||
// If current command is used with different settings we need to add a new command
|
// If current command is used with different settings we need to add a new command
|
||||||
const ImTextureID curr_texture_id = GetCurrentTextureId();
|
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||||
ImDrawCmd* curr_cmd = CmdBuffer.Size ? &CmdBuffer.back() : NULL;
|
if (curr_cmd->ElemCount != 0 && curr_cmd->TextureId != _CmdHeader.TextureId)
|
||||||
if (!curr_cmd || (curr_cmd->ElemCount != 0 && curr_cmd->TextureId != curr_texture_id) || curr_cmd->UserCallback != NULL)
|
|
||||||
{
|
{
|
||||||
AddDrawCmd();
|
AddDrawCmd();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
IM_ASSERT(curr_cmd->UserCallback == NULL);
|
||||||
|
|
||||||
// Try to merge with previous command if it matches, else use current command
|
// Try to merge with previous command if it matches, else use current command
|
||||||
ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL;
|
ImDrawCmd* prev_cmd = curr_cmd - 1;
|
||||||
if (curr_cmd->ElemCount == 0 && prev_cmd && prev_cmd->TextureId == curr_texture_id && memcmp(&prev_cmd->ClipRect, &GetCurrentClipRect(), sizeof(ImVec4)) == 0 && prev_cmd->UserCallback == NULL)
|
if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1 && ImDrawCmd_HeaderCompare(&_CmdHeader, prev_cmd) == 0 && prev_cmd->UserCallback == NULL)
|
||||||
|
{
|
||||||
CmdBuffer.pop_back();
|
CmdBuffer.pop_back();
|
||||||
else
|
return;
|
||||||
curr_cmd->TextureId = curr_texture_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef GetCurrentClipRect
|
curr_cmd->TextureId = _CmdHeader.TextureId;
|
||||||
#undef GetCurrentTextureId
|
}
|
||||||
|
|
||||||
|
void ImDrawList::_OnChangedVtxOffset()
|
||||||
|
{
|
||||||
|
// We don't need to compare curr_cmd->VtxOffset != _CmdHeader.VtxOffset because we know it'll be different at the time we call this.
|
||||||
|
_VtxCurrentIdx = 0;
|
||||||
|
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||||
|
IM_ASSERT(curr_cmd->VtxOffset != _CmdHeader.VtxOffset);
|
||||||
|
if (curr_cmd->ElemCount != 0)
|
||||||
|
{
|
||||||
|
AddDrawCmd();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
IM_ASSERT(curr_cmd->UserCallback == NULL);
|
||||||
|
curr_cmd->VtxOffset = _CmdHeader.VtxOffset;
|
||||||
|
}
|
||||||
|
|
||||||
// Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
|
// Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
|
||||||
void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_current_clip_rect)
|
void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_current_clip_rect)
|
||||||
{
|
{
|
||||||
ImVec4 cr(cr_min.x, cr_min.y, cr_max.x, cr_max.y);
|
ImVec4 cr(cr_min.x, cr_min.y, cr_max.x, cr_max.y);
|
||||||
if (intersect_with_current_clip_rect && _ClipRectStack.Size)
|
if (intersect_with_current_clip_rect)
|
||||||
{
|
{
|
||||||
ImVec4 current = _ClipRectStack.Data[_ClipRectStack.Size-1];
|
ImVec4 current = _CmdHeader.ClipRect;
|
||||||
if (cr.x < current.x) cr.x = current.x;
|
if (cr.x < current.x) cr.x = current.x;
|
||||||
if (cr.y < current.y) cr.y = current.y;
|
if (cr.y < current.y) cr.y = current.y;
|
||||||
if (cr.z > current.z) cr.z = current.z;
|
if (cr.z > current.z) cr.z = current.z;
|
||||||
@ -511,7 +548,8 @@ void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_
|
|||||||
cr.w = ImMax(cr.y, cr.w);
|
cr.w = ImMax(cr.y, cr.w);
|
||||||
|
|
||||||
_ClipRectStack.push_back(cr);
|
_ClipRectStack.push_back(cr);
|
||||||
UpdateClipRect();
|
_CmdHeader.ClipRect = cr;
|
||||||
|
_OnChangedClipRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::PushClipRectFullScreen()
|
void ImDrawList::PushClipRectFullScreen()
|
||||||
@ -521,22 +559,23 @@ void ImDrawList::PushClipRectFullScreen()
|
|||||||
|
|
||||||
void ImDrawList::PopClipRect()
|
void ImDrawList::PopClipRect()
|
||||||
{
|
{
|
||||||
IM_ASSERT(_ClipRectStack.Size > 0);
|
|
||||||
_ClipRectStack.pop_back();
|
_ClipRectStack.pop_back();
|
||||||
UpdateClipRect();
|
_CmdHeader.ClipRect = (_ClipRectStack.Size == 0) ? _Data->ClipRectFullscreen : _ClipRectStack.Data[_ClipRectStack.Size - 1];
|
||||||
|
_OnChangedClipRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::PushTextureID(ImTextureID texture_id)
|
void ImDrawList::PushTextureID(ImTextureID texture_id)
|
||||||
{
|
{
|
||||||
_TextureIdStack.push_back(texture_id);
|
_TextureIdStack.push_back(texture_id);
|
||||||
UpdateTextureID();
|
_CmdHeader.TextureId = texture_id;
|
||||||
|
_OnChangedTextureID();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::PopTextureID()
|
void ImDrawList::PopTextureID()
|
||||||
{
|
{
|
||||||
IM_ASSERT(_TextureIdStack.Size > 0);
|
|
||||||
_TextureIdStack.pop_back();
|
_TextureIdStack.pop_back();
|
||||||
UpdateTextureID();
|
_CmdHeader.TextureId = (_TextureIdStack.Size == 0) ? (ImTextureID)NULL : _TextureIdStack.Data[_TextureIdStack.Size - 1];
|
||||||
|
_OnChangedTextureID();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reserve space for a number of vertices and indices.
|
// Reserve space for a number of vertices and indices.
|
||||||
@ -548,13 +587,12 @@ void ImDrawList::PrimReserve(int idx_count, int vtx_count)
|
|||||||
IM_ASSERT_PARANOID(idx_count >= 0 && vtx_count >= 0);
|
IM_ASSERT_PARANOID(idx_count >= 0 && vtx_count >= 0);
|
||||||
if (sizeof(ImDrawIdx) == 2 && (_VtxCurrentIdx + vtx_count >= (1 << 16)) && (Flags & ImDrawListFlags_AllowVtxOffset))
|
if (sizeof(ImDrawIdx) == 2 && (_VtxCurrentIdx + vtx_count >= (1 << 16)) && (Flags & ImDrawListFlags_AllowVtxOffset))
|
||||||
{
|
{
|
||||||
_VtxCurrentOffset = VtxBuffer.Size;
|
_CmdHeader.VtxOffset = VtxBuffer.Size;
|
||||||
_VtxCurrentIdx = 0;
|
_OnChangedVtxOffset();
|
||||||
AddDrawCmd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImDrawCmd& draw_cmd = CmdBuffer.Data[CmdBuffer.Size - 1];
|
ImDrawCmd* draw_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||||
draw_cmd.ElemCount += idx_count;
|
draw_cmd->ElemCount += idx_count;
|
||||||
|
|
||||||
int vtx_buffer_old_size = VtxBuffer.Size;
|
int vtx_buffer_old_size = VtxBuffer.Size;
|
||||||
VtxBuffer.resize(vtx_buffer_old_size + vtx_count);
|
VtxBuffer.resize(vtx_buffer_old_size + vtx_count);
|
||||||
@ -570,8 +608,8 @@ void ImDrawList::PrimUnreserve(int idx_count, int vtx_count)
|
|||||||
{
|
{
|
||||||
IM_ASSERT_PARANOID(idx_count >= 0 && vtx_count >= 0);
|
IM_ASSERT_PARANOID(idx_count >= 0 && vtx_count >= 0);
|
||||||
|
|
||||||
ImDrawCmd& draw_cmd = CmdBuffer.Data[CmdBuffer.Size - 1];
|
ImDrawCmd* draw_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||||
draw_cmd.ElemCount -= idx_count;
|
draw_cmd->ElemCount -= idx_count;
|
||||||
VtxBuffer.shrink(VtxBuffer.Size - vtx_count);
|
VtxBuffer.shrink(VtxBuffer.Size - vtx_count);
|
||||||
IdxBuffer.shrink(IdxBuffer.Size - idx_count);
|
IdxBuffer.shrink(IdxBuffer.Size - idx_count);
|
||||||
}
|
}
|
||||||
@ -1225,9 +1263,9 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos,
|
|||||||
if (font_size == 0.0f)
|
if (font_size == 0.0f)
|
||||||
font_size = _Data->FontSize;
|
font_size = _Data->FontSize;
|
||||||
|
|
||||||
IM_ASSERT(font->ContainerAtlas->TexID == _TextureIdStack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font.
|
IM_ASSERT(font->ContainerAtlas->TexID == _CmdHeader.TextureId); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font.
|
||||||
|
|
||||||
ImVec4 clip_rect = _ClipRectStack.back();
|
ImVec4 clip_rect = _CmdHeader.ClipRect;
|
||||||
if (cpu_fine_clip_rect)
|
if (cpu_fine_clip_rect)
|
||||||
{
|
{
|
||||||
clip_rect.x = ImMax(clip_rect.x, cpu_fine_clip_rect->x);
|
clip_rect.x = ImMax(clip_rect.x, cpu_fine_clip_rect->x);
|
||||||
@ -1248,7 +1286,7 @@ void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& p_min, cons
|
|||||||
if ((col & IM_COL32_A_MASK) == 0)
|
if ((col & IM_COL32_A_MASK) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back();
|
const bool push_texture_id = user_texture_id != _CmdHeader.TextureId;
|
||||||
if (push_texture_id)
|
if (push_texture_id)
|
||||||
PushTextureID(user_texture_id);
|
PushTextureID(user_texture_id);
|
||||||
|
|
||||||
@ -1264,7 +1302,7 @@ void ImDrawList::AddImageQuad(ImTextureID user_texture_id, const ImVec2& p1, con
|
|||||||
if ((col & IM_COL32_A_MASK) == 0)
|
if ((col & IM_COL32_A_MASK) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back();
|
const bool push_texture_id = user_texture_id != _CmdHeader.TextureId;
|
||||||
if (push_texture_id)
|
if (push_texture_id)
|
||||||
PushTextureID(user_texture_id);
|
PushTextureID(user_texture_id);
|
||||||
|
|
||||||
@ -1347,27 +1385,20 @@ void ImDrawListSplitter::Split(ImDrawList* draw_list, int channels_count)
|
|||||||
if (_Channels[i]._CmdBuffer.Size == 0)
|
if (_Channels[i]._CmdBuffer.Size == 0)
|
||||||
{
|
{
|
||||||
ImDrawCmd draw_cmd;
|
ImDrawCmd draw_cmd;
|
||||||
draw_cmd.ClipRect = draw_list->_ClipRectStack.back();
|
ImDrawCmd_HeaderCopy(&draw_cmd, &draw_list->_CmdHeader); // Copy ClipRect, TextureId, VtxOffset
|
||||||
draw_cmd.TextureId = draw_list->_TextureIdStack.back();
|
|
||||||
_Channels[i]._CmdBuffer.push_back(draw_cmd);
|
_Channels[i]._CmdBuffer.push_back(draw_cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool CanMergeDrawCommands(ImDrawCmd* a, ImDrawCmd* b)
|
|
||||||
{
|
|
||||||
return memcmp(&a->ClipRect, &b->ClipRect, sizeof(a->ClipRect)) == 0 && a->TextureId == b->TextureId && a->VtxOffset == b->VtxOffset && !a->UserCallback && !b->UserCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImDrawListSplitter::Merge(ImDrawList* draw_list)
|
void ImDrawListSplitter::Merge(ImDrawList* draw_list)
|
||||||
{
|
{
|
||||||
// Note that we never use or rely on channels.Size because it is merely a buffer that we never shrink back to 0 to keep all sub-buffers ready for use.
|
// Note that we never use or rely on _Channels.Size because it is merely a buffer that we never shrink back to 0 to keep all sub-buffers ready for use.
|
||||||
if (_Count <= 1)
|
if (_Count <= 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SetCurrentChannel(draw_list, 0);
|
SetCurrentChannel(draw_list, 0);
|
||||||
if (draw_list->CmdBuffer.Size != 0 && draw_list->CmdBuffer.back().ElemCount == 0)
|
draw_list->_PopUnusedDrawCmd();
|
||||||
draw_list->CmdBuffer.pop_back();
|
|
||||||
|
|
||||||
// Calculate our final buffer sizes. Also fix the incorrect IdxOffset values in each command.
|
// Calculate our final buffer sizes. Also fix the incorrect IdxOffset values in each command.
|
||||||
int new_cmd_buffer_count = 0;
|
int new_cmd_buffer_count = 0;
|
||||||
@ -1377,15 +1408,22 @@ void ImDrawListSplitter::Merge(ImDrawList* draw_list)
|
|||||||
for (int i = 1; i < _Count; i++)
|
for (int i = 1; i < _Count; i++)
|
||||||
{
|
{
|
||||||
ImDrawChannel& ch = _Channels[i];
|
ImDrawChannel& ch = _Channels[i];
|
||||||
|
|
||||||
|
// Equivalent of PopUnusedDrawCmd() for this channel's cmdbuffer and except we don't need to test for UserCallback.
|
||||||
if (ch._CmdBuffer.Size > 0 && ch._CmdBuffer.back().ElemCount == 0)
|
if (ch._CmdBuffer.Size > 0 && ch._CmdBuffer.back().ElemCount == 0)
|
||||||
ch._CmdBuffer.pop_back();
|
ch._CmdBuffer.pop_back();
|
||||||
if (ch._CmdBuffer.Size > 0 && last_cmd != NULL && CanMergeDrawCommands(last_cmd, &ch._CmdBuffer[0]))
|
|
||||||
|
if (ch._CmdBuffer.Size > 0 && last_cmd != NULL)
|
||||||
|
{
|
||||||
|
ImDrawCmd* next_cmd = &ch._CmdBuffer[0];
|
||||||
|
if (ImDrawCmd_HeaderCompare(last_cmd, next_cmd) == 0 && last_cmd->UserCallback == NULL && next_cmd->UserCallback == NULL)
|
||||||
{
|
{
|
||||||
// Merge previous channel last draw command with current channel first draw command if matching.
|
// Merge previous channel last draw command with current channel first draw command if matching.
|
||||||
last_cmd->ElemCount += ch._CmdBuffer[0].ElemCount;
|
last_cmd->ElemCount += next_cmd->ElemCount;
|
||||||
idx_offset += ch._CmdBuffer[0].ElemCount;
|
idx_offset += next_cmd->ElemCount;
|
||||||
ch._CmdBuffer.erase(ch._CmdBuffer.Data); // FIXME-OPT: Improve for multiple merges.
|
ch._CmdBuffer.erase(ch._CmdBuffer.Data); // FIXME-OPT: Improve for multiple merges.
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (ch._CmdBuffer.Size > 0)
|
if (ch._CmdBuffer.Size > 0)
|
||||||
last_cmd = &ch._CmdBuffer.back();
|
last_cmd = &ch._CmdBuffer.back();
|
||||||
new_cmd_buffer_count += ch._CmdBuffer.Size;
|
new_cmd_buffer_count += ch._CmdBuffer.Size;
|
||||||
@ -1409,8 +1447,18 @@ void ImDrawListSplitter::Merge(ImDrawList* draw_list)
|
|||||||
if (int sz = ch._IdxBuffer.Size) { memcpy(idx_write, ch._IdxBuffer.Data, sz * sizeof(ImDrawIdx)); idx_write += sz; }
|
if (int sz = ch._IdxBuffer.Size) { memcpy(idx_write, ch._IdxBuffer.Data, sz * sizeof(ImDrawIdx)); idx_write += sz; }
|
||||||
}
|
}
|
||||||
draw_list->_IdxWritePtr = idx_write;
|
draw_list->_IdxWritePtr = idx_write;
|
||||||
draw_list->UpdateClipRect(); // We call this instead of AddDrawCmd(), so that empty channels won't produce an extra draw call.
|
|
||||||
draw_list->UpdateTextureID();
|
// Ensure there's always a non-callback draw command trailing the command-buffer
|
||||||
|
if (draw_list->CmdBuffer.Size == 0 || draw_list->CmdBuffer.back().UserCallback != NULL)
|
||||||
|
draw_list->AddDrawCmd();
|
||||||
|
|
||||||
|
// If current command is used with different settings we need to add a new command
|
||||||
|
ImDrawCmd* curr_cmd = &draw_list->CmdBuffer.Data[draw_list->CmdBuffer.Size - 1];
|
||||||
|
if (curr_cmd->ElemCount == 0)
|
||||||
|
ImDrawCmd_HeaderCopy(curr_cmd, &draw_list->_CmdHeader); // Copy ClipRect, TextureId, VtxOffset
|
||||||
|
else if (ImDrawCmd_HeaderCompare(curr_cmd, &draw_list->_CmdHeader) != 0)
|
||||||
|
draw_list->AddDrawCmd();
|
||||||
|
|
||||||
_Count = 1;
|
_Count = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1419,6 +1467,7 @@ void ImDrawListSplitter::SetCurrentChannel(ImDrawList* draw_list, int idx)
|
|||||||
IM_ASSERT(idx >= 0 && idx < _Count);
|
IM_ASSERT(idx >= 0 && idx < _Count);
|
||||||
if (_Current == idx)
|
if (_Current == idx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Overwrite ImVector (12/16 bytes), four times. This is merely a silly optimization instead of doing .swap()
|
// Overwrite ImVector (12/16 bytes), four times. This is merely a silly optimization instead of doing .swap()
|
||||||
memcpy(&_Channels.Data[_Current]._CmdBuffer, &draw_list->CmdBuffer, sizeof(draw_list->CmdBuffer));
|
memcpy(&_Channels.Data[_Current]._CmdBuffer, &draw_list->CmdBuffer, sizeof(draw_list->CmdBuffer));
|
||||||
memcpy(&_Channels.Data[_Current]._IdxBuffer, &draw_list->IdxBuffer, sizeof(draw_list->IdxBuffer));
|
memcpy(&_Channels.Data[_Current]._IdxBuffer, &draw_list->IdxBuffer, sizeof(draw_list->IdxBuffer));
|
||||||
@ -1426,6 +1475,13 @@ void ImDrawListSplitter::SetCurrentChannel(ImDrawList* draw_list, int idx)
|
|||||||
memcpy(&draw_list->CmdBuffer, &_Channels.Data[idx]._CmdBuffer, sizeof(draw_list->CmdBuffer));
|
memcpy(&draw_list->CmdBuffer, &_Channels.Data[idx]._CmdBuffer, sizeof(draw_list->CmdBuffer));
|
||||||
memcpy(&draw_list->IdxBuffer, &_Channels.Data[idx]._IdxBuffer, sizeof(draw_list->IdxBuffer));
|
memcpy(&draw_list->IdxBuffer, &_Channels.Data[idx]._IdxBuffer, sizeof(draw_list->IdxBuffer));
|
||||||
draw_list->_IdxWritePtr = draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size;
|
draw_list->_IdxWritePtr = draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size;
|
||||||
|
|
||||||
|
// If current command is used with different settings we need to add a new command
|
||||||
|
ImDrawCmd* curr_cmd = &draw_list->CmdBuffer.Data[draw_list->CmdBuffer.Size - 1];
|
||||||
|
if (curr_cmd->ElemCount == 0)
|
||||||
|
ImDrawCmd_HeaderCopy(curr_cmd, &draw_list->_CmdHeader); // Copy ClipRect, TextureId, VtxOffset
|
||||||
|
else if (ImDrawCmd_HeaderCompare(curr_cmd, &draw_list->_CmdHeader) != 0)
|
||||||
|
draw_list->AddDrawCmd();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -2853,7 +2909,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allow wrapping after punctuation.
|
// Allow wrapping after punctuation.
|
||||||
inside_word = !(c == '.' || c == ',' || c == ';' || c == '!' || c == '?' || c == '\"');
|
inside_word = (c != '.' && c != ',' && c != ';' && c != '!' && c != '?' && c != '\"');
|
||||||
}
|
}
|
||||||
|
|
||||||
// We ignore blank width at the end of the line (they can be skipped)
|
// We ignore blank width at the end of the line (they can be skipped)
|
||||||
@ -3245,8 +3301,8 @@ void ImGui::RenderMouseCursor(ImDrawList* draw_list, ImVec2 pos, float scale, Im
|
|||||||
pos -= offset;
|
pos -= offset;
|
||||||
const ImTextureID tex_id = font_atlas->TexID;
|
const ImTextureID tex_id = font_atlas->TexID;
|
||||||
draw_list->PushTextureID(tex_id);
|
draw_list->PushTextureID(tex_id);
|
||||||
draw_list->AddImage(tex_id, pos + ImVec2(1,0)*scale, pos + ImVec2(1,0)*scale + size*scale, uv[2], uv[3], col_shadow);
|
draw_list->AddImage(tex_id, pos + ImVec2(1, 0) * scale, pos + (ImVec2(1, 0) + size) * scale, uv[2], uv[3], col_shadow);
|
||||||
draw_list->AddImage(tex_id, pos + ImVec2(2,0)*scale, pos + ImVec2(2,0)*scale + size*scale, uv[2], uv[3], col_shadow);
|
draw_list->AddImage(tex_id, pos + ImVec2(2, 0) * scale, pos + (ImVec2(2, 0) + size) * scale, uv[2], uv[3], col_shadow);
|
||||||
draw_list->AddImage(tex_id, pos, pos + size * scale, uv[2], uv[3], col_border);
|
draw_list->AddImage(tex_id, pos, pos + size * scale, uv[2], uv[3], col_border);
|
||||||
draw_list->AddImage(tex_id, pos, pos + size * scale, uv[0], uv[1], col_fill);
|
draw_list->AddImage(tex_id, pos, pos + size * scale, uv[0], uv[1], col_fill);
|
||||||
draw_list->PopTextureID();
|
draw_list->PopTextureID();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.77 WIP
|
// dear imgui, v1.77
|
||||||
// (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!
|
||||||
@ -57,15 +57,16 @@ Index of this file:
|
|||||||
// Clang/GCC warnings with -Weverything
|
// Clang/GCC warnings with -Weverything
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
|
#if __has_warning("-Wunknown-warning-option")
|
||||||
|
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx'
|
||||||
|
#endif
|
||||||
|
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
|
||||||
#pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h
|
#pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h
|
||||||
#pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h
|
#pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h
|
||||||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||||
#if __has_warning("-Wzero-as-null-pointer-constant")
|
|
||||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
||||||
#endif
|
|
||||||
#if __has_warning("-Wdouble-promotion")
|
|
||||||
#pragma clang diagnostic ignored "-Wdouble-promotion"
|
#pragma clang diagnostic ignored "-Wdouble-promotion"
|
||||||
#endif
|
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||||
@ -151,7 +152,7 @@ namespace ImStb
|
|||||||
#undef STB_TEXTEDIT_CHARTYPE
|
#undef STB_TEXTEDIT_CHARTYPE
|
||||||
#define STB_TEXTEDIT_STRING ImGuiInputTextState
|
#define STB_TEXTEDIT_STRING ImGuiInputTextState
|
||||||
#define STB_TEXTEDIT_CHARTYPE ImWchar
|
#define STB_TEXTEDIT_CHARTYPE ImWchar
|
||||||
#define STB_TEXTEDIT_GETWIDTH_NEWLINE -1.0f
|
#define STB_TEXTEDIT_GETWIDTH_NEWLINE (-1.0f)
|
||||||
#define STB_TEXTEDIT_UNDOSTATECOUNT 99
|
#define STB_TEXTEDIT_UNDOSTATECOUNT 99
|
||||||
#define STB_TEXTEDIT_UNDOCHARCOUNT 999
|
#define STB_TEXTEDIT_UNDOCHARCOUNT 999
|
||||||
#include "imstb_textedit.h"
|
#include "imstb_textedit.h"
|
||||||
@ -377,9 +378,9 @@ static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t)
|
|||||||
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); }
|
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); }
|
||||||
static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); }
|
static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); }
|
||||||
static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; }
|
static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; }
|
||||||
static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; }
|
static inline float ImLengthSqr(const ImVec2& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y); }
|
||||||
static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y + lhs.z*lhs.z + lhs.w*lhs.w; }
|
static inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); }
|
||||||
static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / ImSqrt(d); return fail_value; }
|
static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return 1.0f / ImSqrt(d); return fail_value; }
|
||||||
static inline float ImFloor(float f) { return (float)(int)(f); }
|
static inline float ImFloor(float f) { return (float)(int)(f); }
|
||||||
static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); }
|
static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); }
|
||||||
static inline int ImModPositive(int a, int b) { return (a + b) % b; }
|
static inline int ImModPositive(int a, int b) { return (a + b) % b; }
|
||||||
@ -451,6 +452,7 @@ struct IMGUI_API ImRect
|
|||||||
void ClipWithFull(const ImRect& r) { Min = ImClamp(Min, r.Min, r.Max); Max = ImClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped.
|
void ClipWithFull(const ImRect& r) { Min = ImClamp(Min, r.Min, r.Max); Max = ImClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped.
|
||||||
void Floor() { Min.x = IM_FLOOR(Min.x); Min.y = IM_FLOOR(Min.y); Max.x = IM_FLOOR(Max.x); Max.y = IM_FLOOR(Max.y); }
|
void Floor() { Min.x = IM_FLOOR(Min.x); Min.y = IM_FLOOR(Min.y); Max.x = IM_FLOOR(Max.x); Max.y = IM_FLOOR(Max.y); }
|
||||||
bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; }
|
bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; }
|
||||||
|
ImVec4 ToVec4() const { return ImVec4(Min.x, Min.y, Max.x, Max.y); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper: ImBitArray
|
// Helper: ImBitArray
|
||||||
@ -1036,7 +1038,8 @@ struct ImGuiColumns
|
|||||||
float LineMinY, LineMaxY;
|
float LineMinY, LineMaxY;
|
||||||
float HostCursorPosY; // Backup of CursorPos at the time of BeginColumns()
|
float HostCursorPosY; // Backup of CursorPos at the time of BeginColumns()
|
||||||
float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns()
|
float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns()
|
||||||
ImRect HostClipRect; // Backup of ClipRect at the time of BeginColumns()
|
ImRect HostInitialClipRect; // Backup of ClipRect at the time of BeginColumns()
|
||||||
|
ImRect HostBackupClipRect; // Backup of ClipRect during PushColumnsBackground()/PopColumnsBackground()
|
||||||
ImRect HostWorkRect; // Backup of WorkRect at the time of BeginColumns()
|
ImRect HostWorkRect; // Backup of WorkRect at the time of BeginColumns()
|
||||||
ImVector<ImGuiColumnData> Columns;
|
ImVector<ImGuiColumnData> Columns;
|
||||||
ImDrawListSplitter Splitter;
|
ImDrawListSplitter Splitter;
|
||||||
@ -1747,7 +1750,7 @@ struct IMGUI_API ImGuiWindow
|
|||||||
ImVec2 ContentSize; // Size of contents/scrollable client area (calculated from the extents reach of the cursor) from previous frame. Does not include window decoration or window padding.
|
ImVec2 ContentSize; // Size of contents/scrollable client area (calculated from the extents reach of the cursor) from previous frame. Does not include window decoration or window padding.
|
||||||
ImVec2 ContentSizeExplicit; // Size of contents/scrollable client area explicitly request by the user via SetNextWindowContentSize().
|
ImVec2 ContentSizeExplicit; // Size of contents/scrollable client area explicitly request by the user via SetNextWindowContentSize().
|
||||||
ImVec2 WindowPadding; // Window padding at the time of Begin().
|
ImVec2 WindowPadding; // Window padding at the time of Begin().
|
||||||
float WindowRounding; // Window rounding at the time of Begin().
|
float WindowRounding; // Window rounding at the time of Begin(). May be clamped lower to avoid rendering artifacts with title bar, menu bar etc.
|
||||||
float WindowBorderSize; // Window border size at the time of Begin().
|
float WindowBorderSize; // Window border size at the time of Begin().
|
||||||
int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)!
|
int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)!
|
||||||
ImGuiID MoveId; // == window->GetID("#MOVE")
|
ImGuiID MoveId; // == window->GetID("#MOVE")
|
||||||
@ -1766,7 +1769,7 @@ struct IMGUI_API ImGuiWindow
|
|||||||
bool WantCollapseToggle;
|
bool WantCollapseToggle;
|
||||||
bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed)
|
bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed)
|
||||||
bool Appearing; // Set during the frame where the window is appearing (or re-appearing)
|
bool Appearing; // Set during the frame where the window is appearing (or re-appearing)
|
||||||
bool Hidden; // Do not display (== (HiddenFrames*** > 0))
|
bool Hidden; // Do not display (== HiddenFrames*** > 0)
|
||||||
bool IsFallbackWindow; // Set on the "Debug##Default" window.
|
bool IsFallbackWindow; // Set on the "Debug##Default" window.
|
||||||
bool HasCloseButton; // Set when the window has a close button (p_open != NULL)
|
bool HasCloseButton; // Set when the window has a close button (p_open != NULL)
|
||||||
signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3)
|
signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3)
|
||||||
@ -2063,10 +2066,10 @@ namespace ImGui
|
|||||||
|
|
||||||
// Popups, Modals, Tooltips
|
// Popups, Modals, Tooltips
|
||||||
IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags);
|
IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags);
|
||||||
IMGUI_API void OpenPopupEx(ImGuiID id);
|
IMGUI_API void OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags = ImGuiPopupFlags_None);
|
||||||
IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup);
|
IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup);
|
||||||
IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup);
|
IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup);
|
||||||
IMGUI_API bool IsPopupOpen(ImGuiID id); // Test for id at current popup stack level (currently begin-ed into); this doesn't scan the whole popup stack!
|
IMGUI_API bool IsPopupOpen(ImGuiID id, ImGuiPopupFlags popup_flags);
|
||||||
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags);
|
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags);
|
||||||
IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, ImGuiTooltipFlags tooltip_flags);
|
IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, ImGuiTooltipFlags tooltip_flags);
|
||||||
IMGUI_API ImGuiWindow* GetTopMostPopupModal();
|
IMGUI_API ImGuiWindow* GetTopMostPopupModal();
|
||||||
@ -2156,6 +2159,7 @@ namespace ImGui
|
|||||||
IMGUI_API bool IsDragDropPayloadBeingAccepted();
|
IMGUI_API bool IsDragDropPayloadBeingAccepted();
|
||||||
|
|
||||||
// Internal Columns API (this is not exposed because we will encourage transitioning to the Tables API)
|
// Internal Columns API (this is not exposed because we will encourage transitioning to the Tables API)
|
||||||
|
IMGUI_API void SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect);
|
||||||
IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().
|
IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().
|
||||||
IMGUI_API void EndColumns(); // close columns
|
IMGUI_API void EndColumns(); // close columns
|
||||||
IMGUI_API void PushColumnClipRect(int column_index);
|
IMGUI_API void PushColumnClipRect(int column_index);
|
||||||
@ -2218,6 +2222,7 @@ namespace ImGui
|
|||||||
IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0);
|
IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0);
|
||||||
IMGUI_API void Scrollbar(ImGuiAxis axis);
|
IMGUI_API void Scrollbar(ImGuiAxis axis);
|
||||||
IMGUI_API bool ScrollbarEx(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* p_scroll_v, float avail_v, float contents_v, ImDrawCornerFlags rounding_corners);
|
IMGUI_API bool ScrollbarEx(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* p_scroll_v, float avail_v, float contents_v, ImDrawCornerFlags rounding_corners);
|
||||||
|
IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col);
|
||||||
IMGUI_API ImRect GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis);
|
IMGUI_API ImRect GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis);
|
||||||
IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis);
|
IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis);
|
||||||
IMGUI_API ImGuiID GetWindowResizeID(ImGuiWindow* window, int n); // 0..3: corners, 4..7: borders
|
IMGUI_API ImGuiID GetWindowResizeID(ImGuiWindow* window, int n); // 0..3: corners, 4..7: borders
|
||||||
@ -2289,8 +2294,8 @@ IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned ch
|
|||||||
// [SECTION] Test Engine Hooks (imgui_test_engine)
|
// [SECTION] Test Engine Hooks (imgui_test_engine)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
//#define IMGUI_ENABLE_TEST_ENGINE
|
|
||||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||||
|
extern void ImGuiTestEngineHook_Shutdown(ImGuiContext* ctx);
|
||||||
extern void ImGuiTestEngineHook_PreNewFrame(ImGuiContext* ctx);
|
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);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.77 WIP
|
// dear imgui, v1.77
|
||||||
// (widgets code)
|
// (widgets code)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -58,19 +58,19 @@ Index of this file:
|
|||||||
|
|
||||||
// Clang/GCC warnings with -Weverything
|
// Clang/GCC warnings with -Weverything
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
|
#if __has_warning("-Wunknown-warning-option")
|
||||||
|
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great!
|
||||||
|
#endif
|
||||||
|
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
|
||||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||||||
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
|
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
|
||||||
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
|
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
|
||||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness //
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||||
#if __has_warning("-Wzero-as-null-pointer-constant")
|
|
||||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
|
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
|
||||||
#endif
|
|
||||||
#if __has_warning("-Wdouble-promotion")
|
|
||||||
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
|
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
|
||||||
#endif
|
#pragma clang diagnostic ignored "-Wenum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_')
|
||||||
#if __has_warning("-Wdeprecated-enum-enum-conversion")
|
|
||||||
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||||
#endif
|
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
|
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
|
||||||
@ -557,7 +557,8 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|||||||
if ((flags & ImGuiButtonFlags_PressedOnRelease) && mouse_button_released != -1)
|
if ((flags & ImGuiButtonFlags_PressedOnRelease) && mouse_button_released != -1)
|
||||||
{
|
{
|
||||||
// Repeat mode trumps on release behavior
|
// Repeat mode trumps on release behavior
|
||||||
if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay))
|
const bool has_repeated_at_least_once = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay;
|
||||||
|
if (!has_repeated_at_least_once)
|
||||||
pressed = true;
|
pressed = true;
|
||||||
ClearActiveID();
|
ClearActiveID();
|
||||||
}
|
}
|
||||||
@ -987,28 +988,16 @@ void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// frame_padding < 0: uses FramePadding from style (default)
|
// ImageButton() is flawed as 'id' is always derived from 'texture_id' (see #2464 #1390)
|
||||||
// frame_padding = 0: no framing
|
// We provide this internal helper to write your own variant while we figure out how to redesign the public ImageButton() API.
|
||||||
// frame_padding > 0: set framing size
|
bool ImGui::ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col)
|
||||||
// The color used are the button colors.
|
|
||||||
bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col)
|
|
||||||
{
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
if (window->SkipItems)
|
if (window->SkipItems)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
const ImGuiStyle& style = g.Style;
|
|
||||||
|
|
||||||
// Default to using texture ID as ID. User can still push string/integer prefixes.
|
|
||||||
// We could hash the size/uv to create a unique ID but that would prevent the user from animating UV.
|
|
||||||
PushID((void*)(intptr_t)user_texture_id);
|
|
||||||
const ImGuiID id = window->GetID("#image");
|
|
||||||
PopID();
|
|
||||||
|
|
||||||
const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : style.FramePadding;
|
|
||||||
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding * 2);
|
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding * 2);
|
||||||
const ImRect image_bb(window->DC.CursorPos + padding, window->DC.CursorPos + padding + size);
|
|
||||||
ItemSize(bb);
|
ItemSize(bb);
|
||||||
if (!ItemAdd(bb, id))
|
if (!ItemAdd(bb, id))
|
||||||
return false;
|
return false;
|
||||||
@ -1019,14 +1008,33 @@ bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const I
|
|||||||
// Render
|
// Render
|
||||||
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
||||||
RenderNavHighlight(bb, id);
|
RenderNavHighlight(bb, id);
|
||||||
RenderFrame(bb.Min, bb.Max, col, true, ImClamp((float)ImMin(padding.x, padding.y), 0.0f, style.FrameRounding));
|
RenderFrame(bb.Min, bb.Max, col, true, ImClamp((float)ImMin(padding.x, padding.y), 0.0f, g.Style.FrameRounding));
|
||||||
if (bg_col.w > 0.0f)
|
if (bg_col.w > 0.0f)
|
||||||
window->DrawList->AddRectFilled(image_bb.Min, image_bb.Max, GetColorU32(bg_col));
|
window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, GetColorU32(bg_col));
|
||||||
window->DrawList->AddImage(user_texture_id, image_bb.Min, image_bb.Max, uv0, uv1, GetColorU32(tint_col));
|
window->DrawList->AddImage(texture_id, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
|
||||||
|
|
||||||
return pressed;
|
return pressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// frame_padding < 0: uses FramePadding from style (default)
|
||||||
|
// frame_padding = 0: no framing
|
||||||
|
// frame_padding > 0: set framing size
|
||||||
|
bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
if (window->SkipItems)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Default to using texture ID as ID. User can still push string/integer prefixes.
|
||||||
|
PushID((void*)(intptr_t)user_texture_id);
|
||||||
|
const ImGuiID id = window->GetID("#image");
|
||||||
|
PopID();
|
||||||
|
|
||||||
|
const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : g.Style.FramePadding;
|
||||||
|
return ImageButtonEx(id, user_texture_id, size, uv0, uv1, padding, bg_col, tint_col);
|
||||||
|
}
|
||||||
|
|
||||||
bool ImGui::Checkbox(const char* label, bool* v)
|
bool ImGui::Checkbox(const char* label, bool* v)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
@ -1491,7 +1499,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
|||||||
|
|
||||||
bool hovered, held;
|
bool hovered, held;
|
||||||
bool pressed = ButtonBehavior(frame_bb, id, &hovered, &held);
|
bool pressed = ButtonBehavior(frame_bb, id, &hovered, &held);
|
||||||
bool popup_open = IsPopupOpen(id);
|
bool popup_open = IsPopupOpen(id, ImGuiPopupFlags_None);
|
||||||
|
|
||||||
const ImU32 frame_col = GetColorU32(hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
const ImU32 frame_col = GetColorU32(hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
||||||
const float value_x2 = ImMax(frame_bb.Min.x, frame_bb.Max.x - arrow_size);
|
const float value_x2 = ImMax(frame_bb.Min.x, frame_bb.Max.x - arrow_size);
|
||||||
@ -1516,7 +1524,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
|||||||
{
|
{
|
||||||
if (window->DC.NavLayerCurrent == 0)
|
if (window->DC.NavLayerCurrent == 0)
|
||||||
window->NavLastIds[0] = id;
|
window->NavLastIds[0] = id;
|
||||||
OpenPopupEx(id);
|
OpenPopupEx(id, ImGuiPopupFlags_None);
|
||||||
popup_open = true;
|
popup_open = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3476,18 +3484,22 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
|
|||||||
// Generic named filters
|
// Generic named filters
|
||||||
if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific))
|
if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific))
|
||||||
{
|
{
|
||||||
|
// Allow 0-9 . - + * /
|
||||||
if (flags & ImGuiInputTextFlags_CharsDecimal)
|
if (flags & ImGuiInputTextFlags_CharsDecimal)
|
||||||
if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/'))
|
if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/'))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Allow 0-9 . - + * / e E
|
||||||
if (flags & ImGuiInputTextFlags_CharsScientific)
|
if (flags & ImGuiInputTextFlags_CharsScientific)
|
||||||
if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/') && (c != 'e') && (c != 'E'))
|
if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/') && (c != 'e') && (c != 'E'))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Allow 0-9 a-F A-F
|
||||||
if (flags & ImGuiInputTextFlags_CharsHexadecimal)
|
if (flags & ImGuiInputTextFlags_CharsHexadecimal)
|
||||||
if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F'))
|
if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F'))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Turn a-z into A-Z
|
||||||
if (flags & ImGuiInputTextFlags_CharsUppercase)
|
if (flags & ImGuiInputTextFlags_CharsUppercase)
|
||||||
if (c >= 'a' && c <= 'z')
|
if (c >= 'a' && c <= 'z')
|
||||||
*p_char = (c += (unsigned int)('A' - 'a'));
|
*p_char = (c += (unsigned int)('A' - 'a'));
|
||||||
@ -4293,7 +4305,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
PopFont();
|
PopFont();
|
||||||
|
|
||||||
// Log as text
|
// Log as text
|
||||||
if (g.LogEnabled && !(is_password && !is_displaying_hint))
|
if (g.LogEnabled && (!is_password || is_displaying_hint))
|
||||||
LogRenderedText(&draw_pos, buf_display, buf_display_end);
|
LogRenderedText(&draw_pos, buf_display, buf_display_end);
|
||||||
|
|
||||||
if (label_size.x > 0)
|
if (label_size.x > 0)
|
||||||
@ -4440,7 +4452,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
|||||||
value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]);
|
value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]);
|
||||||
}
|
}
|
||||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||||
OpenPopupOnItemClick("context");
|
OpenPopupContextItem("context");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((flags & ImGuiColorEditFlags_DisplayHex) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0)
|
else if ((flags & ImGuiColorEditFlags_DisplayHex) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0)
|
||||||
@ -4465,7 +4477,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
|||||||
sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]);
|
sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]);
|
||||||
}
|
}
|
||||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||||
OpenPopupOnItemClick("context");
|
OpenPopupContextItem("context");
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiWindow* picker_active_window = NULL;
|
ImGuiWindow* picker_active_window = NULL;
|
||||||
@ -4486,7 +4498,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||||
OpenPopupOnItemClick("context");
|
OpenPopupContextItem("context");
|
||||||
|
|
||||||
if (BeginPopup("picker"))
|
if (BeginPopup("picker"))
|
||||||
{
|
{
|
||||||
@ -4706,7 +4718,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||||
OpenPopupOnItemClick("context");
|
OpenPopupContextItem("context");
|
||||||
}
|
}
|
||||||
else if (flags & ImGuiColorEditFlags_PickerHueBar)
|
else if (flags & ImGuiColorEditFlags_PickerHueBar)
|
||||||
{
|
{
|
||||||
@ -4719,7 +4731,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
|||||||
value_changed = value_changed_sv = true;
|
value_changed = value_changed_sv = true;
|
||||||
}
|
}
|
||||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||||
OpenPopupOnItemClick("context");
|
OpenPopupContextItem("context");
|
||||||
|
|
||||||
// Hue bar logic
|
// Hue bar logic
|
||||||
SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y));
|
SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y));
|
||||||
@ -5632,7 +5644,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags
|
|||||||
if (p_open)
|
if (p_open)
|
||||||
flags |= ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton;
|
flags |= ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton;
|
||||||
bool is_open = TreeNodeBehavior(id, flags, label);
|
bool is_open = TreeNodeBehavior(id, flags, label);
|
||||||
if (p_open)
|
if (p_open != NULL)
|
||||||
{
|
{
|
||||||
// Create a small overlapping close button
|
// Create a small overlapping close button
|
||||||
// FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc.
|
// FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc.
|
||||||
@ -6307,7 +6319,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
const ImGuiStyle& style = g.Style;
|
const ImGuiStyle& style = g.Style;
|
||||||
const ImGuiID id = window->GetID(label);
|
const ImGuiID id = window->GetID(label);
|
||||||
bool menu_is_open = IsPopupOpen(id);
|
bool menu_is_open = IsPopupOpen(id, ImGuiPopupFlags_None);
|
||||||
|
|
||||||
// Sub-menus are ChildWindow so that mouse can be hovering across them (otherwise top-most popup menu would steal focus and not allow hovering on parent menu)
|
// Sub-menus are ChildWindow so that mouse can be hovering across them (otherwise top-most popup menu would steal focus and not allow hovering on parent menu)
|
||||||
ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus;
|
ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus;
|
||||||
@ -6433,7 +6445,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
|||||||
|
|
||||||
if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }'
|
if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }'
|
||||||
want_close = true;
|
want_close = true;
|
||||||
if (want_close && IsPopupOpen(id))
|
if (want_close && IsPopupOpen(id, ImGuiPopupFlags_None))
|
||||||
ClosePopupToLevel(g.BeginPopupStack.Size, true);
|
ClosePopupToLevel(g.BeginPopupStack.Size, true);
|
||||||
|
|
||||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0));
|
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0));
|
||||||
@ -7242,7 +7254,9 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
|||||||
if (tab_bar->Tabs.Size == 1 && !(tab_bar->Flags & ImGuiTabBarFlags_AutoSelectNewTabs))
|
if (tab_bar->Tabs.Size == 1 && !(tab_bar->Flags & ImGuiTabBarFlags_AutoSelectNewTabs))
|
||||||
tab_contents_visible = true;
|
tab_contents_visible = true;
|
||||||
|
|
||||||
if (tab_appearing && !(tab_bar_appearing && !tab_is_new))
|
// Note that tab_is_new is not necessarily the same as tab_appearing! When a tab bar stops being submitted
|
||||||
|
// and then gets submitted again, the tabs will have 'tab_appearing=true' but 'tab_is_new=false'.
|
||||||
|
if (tab_appearing && (!tab_bar_appearing || tab_is_new))
|
||||||
{
|
{
|
||||||
PushItemFlag(ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus, true);
|
PushItemFlag(ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus, true);
|
||||||
ItemAdd(ImRect(), id);
|
ItemAdd(ImRect(), id);
|
||||||
@ -7401,14 +7415,16 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
|||||||
// Tooltip (FIXME: Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer)
|
// Tooltip (FIXME: Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer)
|
||||||
// We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar (which g.HoveredId ignores)
|
// We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar (which g.HoveredId ignores)
|
||||||
if (g.HoveredId == id && !held && g.HoveredIdNotActiveTimer > 0.50f && IsItemHovered())
|
if (g.HoveredId == id && !held && g.HoveredIdNotActiveTimer > 0.50f && IsItemHovered())
|
||||||
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip))
|
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
|
||||||
SetTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
|
SetTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
|
||||||
|
|
||||||
return tab_contents_visible;
|
return tab_contents_visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [Public] This is call is 100% optional but it allows to remove some one-frame glitches when a tab has been unexpectedly removed.
|
// [Public] This is call is 100% optional but it allows to remove some one-frame glitches when a tab has been unexpectedly removed.
|
||||||
// To use it to need to call the function SetTabItemClosed() after BeginTabBar() and before any call to BeginTabItem()
|
// To use it to need to call the function SetTabItemClosed() after BeginTabBar() and before any call to BeginTabItem().
|
||||||
|
// Tabs closed by the close button will automatically be flagged to avoid this issue.
|
||||||
|
// FIXME: We should aim to support calling SetTabItemClosed() after the tab submission (for next frame)
|
||||||
void ImGui::SetTabItemClosed(const char* label)
|
void ImGui::SetTabItemClosed(const char* label)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
@ -7541,6 +7557,7 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
|
|||||||
// [SECTION] Widgets: Columns, BeginColumns, EndColumns, etc.
|
// [SECTION] Widgets: Columns, BeginColumns, EndColumns, etc.
|
||||||
// In the current version, Columns are very weak. Needs to be replaced with a more full-featured system.
|
// In the current version, Columns are very weak. Needs to be replaced with a more full-featured system.
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
// - SetWindowClipRectBeforeSetChannel() [Internal]
|
||||||
// - GetColumnIndex()
|
// - GetColumnIndex()
|
||||||
// - GetColumnCount()
|
// - GetColumnCount()
|
||||||
// - GetColumnOffset()
|
// - GetColumnOffset()
|
||||||
@ -7558,6 +7575,18 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
|
|||||||
// - Columns()
|
// - Columns()
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// [Internal] Small optimization to avoid calls to PopClipRect/SetCurrentChannel/PushClipRect in sequences,
|
||||||
|
// they would meddle many times with the underlying ImDrawCmd.
|
||||||
|
// Instead, we do a preemptive overwrite of clipping rectangle _without_ altering the command-buffer and let
|
||||||
|
// the subsequent single call to SetCurrentChannel() does it things once.
|
||||||
|
void ImGui::SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect)
|
||||||
|
{
|
||||||
|
ImVec4 clip_rect_vec4 = clip_rect.ToVec4();
|
||||||
|
window->ClipRect = clip_rect;
|
||||||
|
window->DrawList->_CmdHeader.ClipRect = clip_rect_vec4;
|
||||||
|
window->DrawList->_ClipRectStack.Data[window->DrawList->_ClipRectStack.Size - 1] = clip_rect_vec4;
|
||||||
|
}
|
||||||
|
|
||||||
int ImGui::GetColumnIndex()
|
int ImGui::GetColumnIndex()
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindowRead();
|
ImGuiWindow* window = GetCurrentWindowRead();
|
||||||
@ -7692,11 +7721,11 @@ void ImGui::PushColumnsBackground()
|
|||||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||||
if (columns->Count == 1)
|
if (columns->Count == 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Optimization: avoid SetCurrentChannel() + PushClipRect()
|
||||||
|
columns->HostBackupClipRect = window->ClipRect;
|
||||||
|
SetWindowClipRectBeforeSetChannel(window, columns->HostInitialClipRect);
|
||||||
columns->Splitter.SetCurrentChannel(window->DrawList, 0);
|
columns->Splitter.SetCurrentChannel(window->DrawList, 0);
|
||||||
int cmd_size = window->DrawList->CmdBuffer.Size;
|
|
||||||
PushClipRect(columns->HostClipRect.Min, columns->HostClipRect.Max, false);
|
|
||||||
IM_UNUSED(cmd_size);
|
|
||||||
IM_ASSERT(cmd_size == window->DrawList->CmdBuffer.Size); // Being in channel 0 this should not have created an ImDrawCmd
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::PopColumnsBackground()
|
void ImGui::PopColumnsBackground()
|
||||||
@ -7705,8 +7734,10 @@ void ImGui::PopColumnsBackground()
|
|||||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||||
if (columns->Count == 1)
|
if (columns->Count == 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Optimization: avoid PopClipRect() + SetCurrentChannel()
|
||||||
|
SetWindowClipRectBeforeSetChannel(window, columns->HostBackupClipRect);
|
||||||
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
|
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
|
||||||
PopClipRect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id)
|
ImGuiColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id)
|
||||||
@ -7754,7 +7785,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
|
|||||||
|
|
||||||
columns->HostCursorPosY = window->DC.CursorPos.y;
|
columns->HostCursorPosY = window->DC.CursorPos.y;
|
||||||
columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x;
|
columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x;
|
||||||
columns->HostClipRect = window->ClipRect;
|
columns->HostInitialClipRect = window->ClipRect;
|
||||||
columns->HostWorkRect = window->WorkRect;
|
columns->HostWorkRect = window->WorkRect;
|
||||||
|
|
||||||
// Set state for first column
|
// Set state for first column
|
||||||
@ -7826,25 +7857,31 @@ void ImGui::NextColumn()
|
|||||||
IM_ASSERT(columns->Current == 0);
|
IM_ASSERT(columns->Current == 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Next column
|
||||||
|
if (++columns->Current == columns->Count)
|
||||||
|
columns->Current = 0;
|
||||||
|
|
||||||
PopItemWidth();
|
PopItemWidth();
|
||||||
PopClipRect();
|
|
||||||
|
// Optimization: avoid PopClipRect() + SetCurrentChannel() + PushClipRect()
|
||||||
|
// (which would needlessly attempt to update commands in the wrong channel, then pop or overwrite them),
|
||||||
|
ImGuiColumnData* column = &columns->Columns[columns->Current];
|
||||||
|
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
|
||||||
|
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
|
||||||
|
|
||||||
const float column_padding = g.Style.ItemSpacing.x;
|
const float column_padding = g.Style.ItemSpacing.x;
|
||||||
columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y);
|
columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y);
|
||||||
if (++columns->Current < columns->Count)
|
if (columns->Current > 0)
|
||||||
{
|
{
|
||||||
// Columns 1+ ignore IndentX (by canceling it out)
|
// Columns 1+ ignore IndentX (by canceling it out)
|
||||||
// FIXME-COLUMNS: Unnecessary, could be locked?
|
// FIXME-COLUMNS: Unnecessary, could be locked?
|
||||||
window->DC.ColumnsOffset.x = GetColumnOffset(columns->Current) - window->DC.Indent.x + column_padding;
|
window->DC.ColumnsOffset.x = GetColumnOffset(columns->Current) - window->DC.Indent.x + column_padding;
|
||||||
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// New row/line
|
// New row/line: column 0 honor IndentX.
|
||||||
// Column 0 honor IndentX
|
|
||||||
window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f);
|
window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f);
|
||||||
columns->Splitter.SetCurrentChannel(window->DrawList, 1);
|
|
||||||
columns->Current = 0;
|
|
||||||
columns->LineMinY = columns->LineMaxY;
|
columns->LineMinY = columns->LineMaxY;
|
||||||
}
|
}
|
||||||
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||||
@ -7852,8 +7889,6 @@ void ImGui::NextColumn()
|
|||||||
window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
|
window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
|
||||||
window->DC.CurrLineTextBaseOffset = 0.0f;
|
window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||||
|
|
||||||
PushColumnClipRect(columns->Current); // FIXME-COLUMNS: Could it be an overwrite?
|
|
||||||
|
|
||||||
// FIXME-COLUMNS: Share code with BeginColumns() - move code on columns setup.
|
// FIXME-COLUMNS: Share code with BeginColumns() - move code on columns setup.
|
||||||
float offset_0 = GetColumnOffset(columns->Current);
|
float offset_0 = GetColumnOffset(columns->Current);
|
||||||
float offset_1 = GetColumnOffset(columns->Current + 1);
|
float offset_1 = GetColumnOffset(columns->Current + 1);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
// - v0.60: (2019/01/10) re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding.
|
// - v0.60: (2019/01/10) re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding.
|
||||||
// - v0.61: (2019/01/15) added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
|
// - v0.61: (2019/01/15) added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
|
||||||
// - v0.62: (2019/02/09) added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!)
|
// - v0.62: (2019/02/09) added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!)
|
||||||
|
// - v0.63: (2020/06/04) fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
|
||||||
|
|
||||||
// Gamma Correct Blending:
|
// Gamma Correct Blending:
|
||||||
// FreeType assumes blending in linear space rather than gamma space.
|
// FreeType assumes blending in linear space rather than gamma space.
|
||||||
@ -467,7 +468,6 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
|
|||||||
ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i];
|
ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i];
|
||||||
|
|
||||||
const FT_Glyph_Metrics* metrics = src_tmp.Font.LoadGlyph(src_glyph.Codepoint);
|
const FT_Glyph_Metrics* metrics = src_tmp.Font.LoadGlyph(src_glyph.Codepoint);
|
||||||
IM_ASSERT(metrics != NULL);
|
|
||||||
if (metrics == NULL)
|
if (metrics == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -559,6 +559,8 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
|
|||||||
ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i];
|
ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i];
|
||||||
stbrp_rect& pack_rect = src_tmp.Rects[glyph_i];
|
stbrp_rect& pack_rect = src_tmp.Rects[glyph_i];
|
||||||
IM_ASSERT(pack_rect.was_packed);
|
IM_ASSERT(pack_rect.was_packed);
|
||||||
|
if (pack_rect.w == 0 && pack_rect.h == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
GlyphInfo& info = src_glyph.Info;
|
GlyphInfo& info = src_glyph.Info;
|
||||||
IM_ASSERT(info.Width + padding <= pack_rect.w);
|
IM_ASSERT(info.Width + padding <= pack_rect.w);
|
||||||
|
@ -81,27 +81,7 @@
|
|||||||
#else
|
#else
|
||||||
#include <stdint.h> // intptr_t
|
#include <stdint.h> // intptr_t
|
||||||
#endif
|
#endif
|
||||||
#if defined(__APPLE__)
|
|
||||||
#include "TargetConditionals.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Auto-enable GLES on matching platforms
|
|
||||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3)
|
|
||||||
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__))
|
|
||||||
#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
|
|
||||||
#elif defined(__EMSCRIPTEN__)
|
|
||||||
#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(IMGUI_IMPL_OPENGL_ES2) || defined(IMGUI_IMPL_OPENGL_ES3)
|
|
||||||
#undef IMGUI_IMPL_OPENGL_LOADER_GL3W
|
|
||||||
#undef IMGUI_IMPL_OPENGL_LOADER_GLEW
|
|
||||||
#undef IMGUI_IMPL_OPENGL_LOADER_GLAD
|
|
||||||
#undef IMGUI_IMPL_OPENGL_LOADER_GLBINDING2
|
|
||||||
#undef IMGUI_IMPL_OPENGL_LOADER_GLBINDING3
|
|
||||||
#undef IMGUI_IMPL_OPENGL_LOADER_CUSTOM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// GL includes
|
// GL includes
|
||||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||||
@ -154,8 +134,8 @@ static GLuint g_GlVersion = 0; // Extracted at runtime usin
|
|||||||
static char g_GlslVersionString[32] = ""; // Specified by user or detected based on compile time GL settings.
|
static char g_GlslVersionString[32] = ""; // Specified by user or detected based on compile time GL settings.
|
||||||
static GLuint g_FontTexture = 0;
|
static GLuint g_FontTexture = 0;
|
||||||
static GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
|
static GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
|
||||||
static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; // Uniforms location
|
static GLint g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; // Uniforms location
|
||||||
static int g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, g_AttribLocationVtxColor = 0; // Vertex attributes location
|
static GLuint g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, g_AttribLocationVtxColor = 0; // Vertex attributes location
|
||||||
static unsigned int g_VboHandle = 0, g_ElementsHandle = 0;
|
static unsigned int g_VboHandle = 0, g_ElementsHandle = 0;
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
@ -170,7 +150,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
|||||||
GLint major, minor;
|
GLint major, minor;
|
||||||
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
||||||
glGetIntegerv(GL_MINOR_VERSION, &minor);
|
glGetIntegerv(GL_MINOR_VERSION, &minor);
|
||||||
g_GlVersion = major * 100 + minor * 10;
|
g_GlVersion = (GLuint)(major * 100 + minor * 10);
|
||||||
#else
|
#else
|
||||||
g_GlVersion = 200; // GLES 2
|
g_GlVersion = 200; // GLES 2
|
||||||
#endif
|
#endif
|
||||||
@ -323,14 +303,14 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||||||
// Backup GL state
|
// Backup GL state
|
||||||
GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture);
|
GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
|
GLuint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_program);
|
||||||
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
GLuint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&last_texture);
|
||||||
#ifdef GL_SAMPLER_BINDING
|
#ifdef GL_SAMPLER_BINDING
|
||||||
GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler);
|
GLuint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, (GLint*)&last_sampler);
|
||||||
#endif
|
#endif
|
||||||
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
GLuint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer);
|
||||||
#ifndef IMGUI_IMPL_OPENGL_ES2
|
#ifndef IMGUI_IMPL_OPENGL_ES2
|
||||||
GLint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object);
|
GLuint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&last_vertex_array_object);
|
||||||
#endif
|
#endif
|
||||||
#ifdef GL_POLYGON_MODE
|
#ifdef GL_POLYGON_MODE
|
||||||
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
||||||
@ -367,8 +347,8 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||||
|
|
||||||
// Upload vertex/index buffers
|
// Upload vertex/index buffers
|
||||||
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW);
|
||||||
|
|
||||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||||
{
|
{
|
||||||
@ -674,9 +654,9 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
|||||||
|
|
||||||
g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
|
g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
|
||||||
g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
|
g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
|
||||||
g_AttribLocationVtxPos = glGetAttribLocation(g_ShaderHandle, "Position");
|
g_AttribLocationVtxPos = (GLuint)glGetAttribLocation(g_ShaderHandle, "Position");
|
||||||
g_AttribLocationVtxUV = glGetAttribLocation(g_ShaderHandle, "UV");
|
g_AttribLocationVtxUV = (GLuint)glGetAttribLocation(g_ShaderHandle, "UV");
|
||||||
g_AttribLocationVtxColor = glGetAttribLocation(g_ShaderHandle, "Color");
|
g_AttribLocationVtxColor = (GLuint)glGetAttribLocation(g_ShaderHandle, "Color");
|
||||||
|
|
||||||
// Create buffers
|
// Create buffers
|
||||||
glGenBuffers(1, &g_VboHandle);
|
glGenBuffers(1, &g_VboHandle);
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// https://github.com/ocornut/imgui
|
// https://github.com/ocornut/imgui
|
||||||
|
|
||||||
// About Desktop OpenGL function loaders:
|
// About Desktop OpenGL function loaders:
|
||||||
// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
|
// Modern Desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
|
||||||
// Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
|
// Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
|
||||||
// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
|
// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
|
||||||
|
|
||||||
@ -37,21 +37,34 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture();
|
|||||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
|
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||||
|
|
||||||
// Specific OpenGL versions
|
// Specific OpenGL ES versions
|
||||||
//#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten
|
//#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten
|
||||||
//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android
|
//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android
|
||||||
|
|
||||||
// Desktop OpenGL: attempt to detect default GL loader based on available header files.
|
// Attempt to auto-detect the default Desktop GL loader based on available header files.
|
||||||
// If auto-detection fails or doesn't select the same GL loader file as used by your application,
|
// If auto-detection fails or doesn't select the same GL loader file as used by your application,
|
||||||
// you are likely to get a crash in ImGui_ImplOpenGL3_Init().
|
// you are likely to get a crash in ImGui_ImplOpenGL3_Init().
|
||||||
// You can explicitly select a loader by using '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line.
|
// You can explicitly select a loader by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line.
|
||||||
#if !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \
|
#if !defined(IMGUI_IMPL_OPENGL_ES2) \
|
||||||
|
&& !defined(IMGUI_IMPL_OPENGL_ES3) \
|
||||||
|
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \
|
||||||
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \
|
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \
|
||||||
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \
|
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \
|
||||||
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) \
|
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) \
|
||||||
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) \
|
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) \
|
||||||
&& !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
|
&& !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
|
||||||
#if defined(__has_include)
|
|
||||||
|
// Try to detect GLES on matching platforms
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include "TargetConditionals.h"
|
||||||
|
#endif
|
||||||
|
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__))
|
||||||
|
#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
|
||||||
|
#elif defined(__EMSCRIPTEN__)
|
||||||
|
#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100"
|
||||||
|
|
||||||
|
// Otherwise try to detect supported Desktop OpenGL loaders..
|
||||||
|
#elif defined(__has_include)
|
||||||
#if __has_include(<GL/glew.h>)
|
#if __has_include(<GL/glew.h>)
|
||||||
#define IMGUI_IMPL_OPENGL_LOADER_GLEW
|
#define IMGUI_IMPL_OPENGL_LOADER_GLEW
|
||||||
#elif __has_include(<glad/glad.h>)
|
#elif __has_include(<glad/glad.h>)
|
||||||
@ -66,7 +79,7 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
|||||||
#error "Cannot detect OpenGL loader!"
|
#error "Cannot detect OpenGL loader!"
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define IMGUI_IMPL_OPENGL_LOADER_GL3W // Default to GL3W
|
#define IMGUI_IMPL_OPENGL_LOADER_GL3W // Default to GL3W embedded in our repository
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user