Merge branch 'master' into docking + tweak dock node padding + use CheckboxFlags with int

# Conflicts:
#	imgui.cpp
#	imgui_demo.cpp
#	imgui_internal.h
docking
ocornut 4 years ago
commit ac08593b96

@ -236,8 +236,8 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
width:width
height:height
width:(NSUInteger)width
height:(NSUInteger)height
mipmapped:NO];
textureDescriptor.usage = MTLTextureUsageShaderRead;
#if TARGET_OS_OSX
@ -246,7 +246,7 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
textureDescriptor.storageMode = MTLStorageModeShared;
#endif
id <MTLTexture> texture = [device newTextureWithDescriptor:textureDescriptor];
[texture replaceRegion:MTLRegionMake2D(0, 0, width, height) mipmapLevel:0 withBytes:pixels bytesPerRow:width * 4];
[texture replaceRegion:MTLRegionMake2D(0, 0, (NSUInteger)width, (NSUInteger)height) mipmapLevel:0 withBytes:pixels bytesPerRow:(NSUInteger)width * 4];
self.fontTexture = texture;
}
@ -437,8 +437,8 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
float R = drawData->DisplayPos.x + drawData->DisplaySize.x;
float T = drawData->DisplayPos.y;
float B = drawData->DisplayPos.y + drawData->DisplaySize.y;
float N = viewport.znear;
float F = viewport.zfar;
float N = (float)viewport.znear;
float F = (float)viewport.zfar;
const float ortho_projection[4][4] =
{
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
@ -466,8 +466,8 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
id<MTLRenderPipelineState> renderPipelineState = [self renderPipelineStateForFrameAndDevice:commandBuffer.device];
size_t vertexBufferLength = drawData->TotalVtxCount * sizeof(ImDrawVert);
size_t indexBufferLength = drawData->TotalIdxCount * sizeof(ImDrawIdx);
size_t vertexBufferLength = (size_t)drawData->TotalVtxCount * sizeof(ImDrawVert);
size_t indexBufferLength = (size_t)drawData->TotalIdxCount * sizeof(ImDrawIdx);
MetalBuffer* vertexBuffer = [self dequeueReusableBufferOfLength:vertexBufferLength device:commandBuffer.device];
MetalBuffer* indexBuffer = [self dequeueReusableBufferOfLength:indexBufferLength device:commandBuffer.device];
@ -484,8 +484,8 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
{
const ImDrawList* cmd_list = drawData->CmdLists[n];
memcpy((char *)vertexBuffer.buffer.contents + vertexBufferOffset, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy((char *)indexBuffer.buffer.contents + indexBufferOffset, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
memcpy((char *)vertexBuffer.buffer.contents + vertexBufferOffset, cmd_list->VtxBuffer.Data, (size_t)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy((char *)indexBuffer.buffer.contents + indexBufferOffset, cmd_list->IdxBuffer.Data, (size_t)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
@ -535,8 +535,8 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
}
}
vertexBufferOffset += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
indexBufferOffset += cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx);
vertexBufferOffset += (size_t)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
indexBufferOffset += (size_t)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx);
}
__weak id weakSelf = self;

@ -172,7 +172,7 @@ void ImGui_ImplOSX_NewFrame(NSView* view)
ImGuiIO& io = ImGui::GetIO();
if (view)
{
const float dpi = [view.window backingScaleFactor];
const float dpi = (float)[view.window backingScaleFactor];
io.DisplaySize = ImVec2((float)view.bounds.size.width, (float)view.bounds.size.height);
io.DisplayFramebufferScale = ImVec2(dpi, dpi);
}
@ -181,7 +181,7 @@ void ImGui_ImplOSX_NewFrame(NSView* view)
if (g_Time == 0.0)
g_Time = CFAbsoluteTimeGetCurrent();
CFAbsoluteTime current_time = CFAbsoluteTimeGetCurrent();
io.DeltaTime = current_time - g_Time;
io.DeltaTime = (float)(current_time - g_Time);
g_Time = current_time;
ImGui_ImplOSX_UpdateMouseCursorAndButtons();
@ -232,7 +232,7 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
NSPoint mousePoint = event.locationInWindow;
mousePoint = [view convertPoint:mousePoint fromView:nil];
mousePoint = NSMakePoint(mousePoint.x, view.bounds.size.height - mousePoint.y);
io.MousePos = ImVec2(mousePoint.x, mousePoint.y);
io.MousePos = ImVec2((float)mousePoint.x, (float)mousePoint.y);
}
if (event.type == NSEventTypeScrollWheel)
@ -259,9 +259,9 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
}
if (fabs(wheel_dx) > 0.0)
io.MouseWheelH += wheel_dx * 0.1f;
io.MouseWheelH += (float)wheel_dx * 0.1f;
if (fabs(wheel_dy) > 0.0)
io.MouseWheel += wheel_dy * 0.1f;
io.MouseWheel += (float)wheel_dy * 0.1f;
return io.WantCaptureMouse;
}
@ -269,8 +269,8 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
if (event.type == NSEventTypeKeyDown)
{
NSString* str = [event characters];
int len = (int)[str length];
for (int i = 0; i < len; i++)
NSUInteger len = [str length];
for (NSUInteger i = 0; i < len; i++)
{
int c = [str characterAtIndex:i];
if (!io.KeyCtrl && !(c >= 0xF700 && c <= 0xFFFF) && c != 127)
@ -289,8 +289,8 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
if (event.type == NSEventTypeKeyUp)
{
NSString* str = [event characters];
int len = (int)[str length];
for (int i = 0; i < len; i++)
NSUInteger len = [str length];
for (NSUInteger i = 0; i < len; i++)
{
int c = [str characterAtIndex:i];
int key = mapCharacterToKey(c);
@ -302,7 +302,6 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
if (event.type == NSEventTypeFlagsChanged)
{
ImGuiIO& io = ImGui::GetIO();
unsigned int flags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
bool oldKeyCtrl = io.KeyCtrl;

@ -119,6 +119,8 @@ Breaking Changes:
- If you were still using the old names, while you are cleaning up, considering enabling
IMGUI_DISABLE_OBSOLETE_FUNCTIONS in imconfig.h even temporarily to have a pass at finding
and removing up old API calls, if any remaining.
- Renamed io.ConfigWindowsMemoryCompactTimer to io.ConfigMemoryCompactTimer as the feature will apply
to other data structures. (#2636)
Other Changes:
@ -129,7 +131,11 @@ Other Changes:
or CollapsingHeader() while dragging. (#1738)
- Drag and Drop: Fix drag and drop to tie same-size drop targets by choosen the later one. Fixes dragging
into a full-window-sized dockspace inside a zero-padded window. (#3519, #2717) [@Black-Cat]
- Checkbox: Added CheckboxFlags() helper with int* type.
- Metrics: Fixed mishandling of ImDrawCmd::VtxOffset in wireframe mesh renderer.
- Misc: Replaced UTF-8 decoder by branchless one by Christopher Wellons (30~40% faster). [@rokups]
Super minor fix handling incomplete UTF-8 contents: if input does not contain enough bytes, decoder
returns IM_UNICODE_CODEPOINT_INVALID and consume remaining bytes (vs old decoded consumed only 1 byte).
- Backends: OpenGL3: Use glGetString(GL_VERSION) query instead of glGetIntegerv(GL_MAJOR_VERSION, ...)
when the later returns zero (e.g. Desktop GL 2.x). (#3530) [@xndcn]
- Backends: OpenGL3: Backup and restore GL_PRIMITIVE_RESTART state. (#3544) [@Xipiryon]

@ -81,7 +81,7 @@ ImGui::EndChild();
ImGui::End();
```
Result:
<br>![sample code output](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/code_sample_03_color.gif)
<br>![sample code output](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v180/code_sample_04_color.gif)
Dear ImGui allows you to **create elaborate tools** as well as very short-lived ones. On the extreme side of short-livedness: using the Edit&Continue (hot code reload) feature of modern compilers you can add a few widgets to tweaks variables while your application is running, and remove the code a minute later! Dear ImGui is not just for tweaking values. You can use it to trace a running algorithm by just emitting text commands. You can use it along with your own reflection data to browse your dataset live. You can use it to expose the internals of a subsystem in your engine, to create a logger, an inspection tool, a profiler, a debugger, an entire game making editor/framework, etc.
@ -119,11 +119,14 @@ Officially maintained backends/bindings (in repository):
- Platforms: GLFW, SDL2, Win32, Glut, OSX.
- Frameworks: Emscripten, Allegro5, Marmalade.
Third-party backends/bindings (see [Bindings](https://github.com/ocornut/imgui/wiki/Bindings/) page):
[Third-party backends/bindings](https://github.com/ocornut/imgui/wiki/Bindings) wiki page:
- Languages: C, C# and: Beef, ChaiScript, Crystal, D, Go, Haskell, Haxe/hxcpp, Java, JavaScript, Julia, Kotlin, Lua, Odin, Pascal, PureBasic, Python, Ruby, Rust, Swift...
- Frameworks: AGS/Adventure Game Studio, Amethyst, bsf, Cinder, Cocos2d-x, Diligent Engine, Flexium, GML/Game Maker Studio2, Godot, GTK3+OpenGL3, Irrlicht Engine, LÖVE+LUA, Magnum, NanoRT, nCine, Nim Game Lib, Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, Photoshop, px_render, Qt/QtDirect3D, SFML, Sokol, Unity, Unreal Engine 4, vtk, Win32 GDI, WxWidgets.
- Note that C bindings ([cimgui](https://github.com/cimgui/cimgui)) are auto-generated, you can use its json/lua output to generate bindings for other languages.
[Useful widgets and extensions](https://github.com/ocornut/imgui/wiki/Useful-Widgets) wiki page:
- Text editors, node editors, timeline editors, plotting, software renderers, remote network access, memory editors, gizmos etc.
Also see [Wiki](https://github.com/ocornut/imgui/wiki) for more links and ideas.
### Upcoming Changes
@ -140,6 +143,8 @@ Some of the goals for 2020 are:
For more user-submitted screenshots of projects using Dear ImGui, check out the [Gallery Threads](https://github.com/ocornut/imgui/issues/3488)!
For a list of third-party widgets and extensions, check out the [Useful Widgets](https://github.com/ocornut/imgui/wiki/Useful-Widgets) wiki page.
Custom engine
[![screenshot game](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v149/gallery_TheDragonsTrap-01-thumb.jpg)](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
@ -196,7 +201,7 @@ Ongoing Dear ImGui development is financially supported by users and private spo
- [Blizzard](https://careers.blizzard.com/en-us/openings/engineering/all/all/all/1), [Google](https://github.com/google/filament), [Nvidia](https://developer.nvidia.com/nvidia-omniverse), [Ubisoft](https://montreal.ubisoft.com/en/ubisoft-sponsors-user-interface-library-for-c-dear-imgui/)
*Double-chocolate and Salty caramel sponsors*
- [Activision](https://careers.activision.com/c/programmingsoftware-engineering-jobs), [Arkane Studios](https://www.arkane-studios.com), [Dotemu](http://www.dotemu.com), [Framefield](http://framefield.com), [Hexagon](https://hexagonxalt.com/the-technology/xalt-visualization), [Kylotonn](https://www.kylotonn.com), [Media Molecule](http://www.mediamolecule.com), [Mesh Consultants](https://www.meshconsultants.ca), [Mobigame](http://www.mobigame.net), [Nadeo](https://www.nadeo.com), [Next Level Games](https://www.nextlevelgames.com), [RAD Game Tools](http://www.radgametools.com/), [Supercell](http://www.supercell.com), [Remedy Entertainment](https://www.remedygames.com/), [Unit 2 Games](https://unit2games.com/)
- [Activision](https://careers.activision.com/c/programmingsoftware-engineering-jobs), [Arkane Studios](https://www.arkane-studios.com), [Dotemu](http://www.dotemu.com), [Framefield](http://framefield.com), [Grinding Gear Games](https://www.grindinggear.com), [Hexagon](https://hexagonxalt.com/the-technology/xalt-visualization), [Kylotonn](https://www.kylotonn.com), [Media Molecule](http://www.mediamolecule.com), [Mesh Consultants](https://www.meshconsultants.ca), [Mobigame](http://www.mobigame.net), [Nadeo](https://www.nadeo.com), [Next Level Games](https://www.nextlevelgames.com), [RAD Game Tools](http://www.radgametools.com/), [Supercell](http://www.supercell.com), [Remedy Entertainment](https://www.remedygames.com/), [Unit 2 Games](https://unit2games.com/)
From November 2014 to December 2019, ongoing development has also been financially supported by its users on Patreon and through individual donations. Please see [detailed list of Dear ImGui supporters](https://github.com/ocornut/imgui/wiki/Sponsors).

@ -195,7 +195,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- docking: C- after a dock/undock, the Scrollbar Status update in Begin() should use an updated e.g. size_y_for_scrollbars to avoid a 1 frame scrollbar flicker.
- tabs: "there is currently a problem because TabItem() will try to submit their own tooltip after 0.50 second, and this will have the effect of making your tooltip flicker once." -> tooltip priority work
- tabs: close button tends to overlap unsaved-document star
- tabs: close button tends to overlap unsaved-document star
- tabs: consider showing the star at the same spot as the close button, like VS Code does.
- tabs: make EndTabBar fail if users doesn't respect BeginTabBar return value, for consistency/future-proofing.
- tabs: persistent order/focus in BeginTabBar() api (#261, #351)
@ -299,6 +299,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb)
- drag and drop: fix/support/options for overlapping drag sources.
- drag and drop: focus drag target window on hold (even without open)
- drag and drop: releasing a drop shows the "..." tooltip for one frame - since e13e598 (#1725)
- drag and drop: drag source on a group object (would need e.g. an invisible button covering group in EndGroup) https://twitter.com/paniq/status/1121446364909535233
- drag and drop: have some way to know when a drag begin from BeginDragDropSource() pov. (see 2018/01/11 post in #143)

@ -1,3 +1,6 @@
// Dear ImGui: standalone example application for OSX + Metal.
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs
#import <Foundation/Foundation.h>
@ -31,13 +34,15 @@
@implementation ViewController
- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil {
- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
_device = MTLCreateSystemDefaultDevice();
_commandQueue = [_device newCommandQueue];
if (!self.device) {
if (!self.device)
{
NSLog(@"Metal is not supported");
abort();
}
@ -75,11 +80,13 @@
return self;
}
- (MTKView *)mtkView {
- (MTKView *)mtkView
{
return (MTKView *)self.view;
}
- (void)loadView {
- (void)loadView
{
self.view = [[MTKView alloc] initWithFrame:CGRectMake(0, 0, 1200, 720)];
}
@ -104,14 +111,13 @@
// window, we'd want to be much more careful than just ingesting the complete event stream, though we
// do make an effort to be good citizens by passing along events when Dear ImGui doesn't want to capture.
NSEventMask eventMask = NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged | NSEventTypeScrollWheel;
[NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event) {
[NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event)
{
BOOL wantsCapture = ImGui_ImplOSX_HandleEvent(event, self.view);
if (event.type == NSEventTypeKeyDown && wantsCapture) {
if (event.type == NSEventTypeKeyDown && wantsCapture)
return nil;
} else {
else
return event;
}
}];
ImGui_ImplOSX_Init();
@ -174,15 +180,18 @@
// multitouch correctly at all. This causes the "cursor" to behave very erratically
// when there are multiple active touches. But for demo purposes, single-touch
// interaction actually works surprisingly well.
- (void)updateIOWithTouchEvent:(UIEvent *)event {
- (void)updateIOWithTouchEvent:(UIEvent *)event
{
UITouch *anyTouch = event.allTouches.anyObject;
CGPoint touchLocation = [anyTouch locationInView:self.view];
ImGuiIO &io = ImGui::GetIO();
io.MousePos = ImVec2(touchLocation.x, touchLocation.y);
BOOL hasActiveTouch = NO;
for (UITouch *touch in event.allTouches) {
if (touch.phase != UITouchPhaseEnded && touch.phase != UITouchPhaseCancelled) {
for (UITouch *touch in event.allTouches)
{
if (touch.phase != UITouchPhaseEnded && touch.phase != UITouchPhaseCancelled)
{
hasActiveTouch = YES;
break;
}
@ -190,19 +199,23 @@
io.MouseDown[0] = hasActiveTouch;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self updateIOWithTouchEvent:event];
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self updateIOWithTouchEvent:event];
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self updateIOWithTouchEvent:event];
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self updateIOWithTouchEvent:event];
}
@ -212,7 +225,7 @@
- (void)drawInMTKView:(MTKView*)view
{
ImGuiIO &io = ImGui::GetIO();
ImGuiIO& io = ImGui::GetIO();
io.DisplaySize.x = view.bounds.size.width;
io.DisplaySize.y = view.bounds.size.height;
@ -288,8 +301,8 @@
// Rendering
ImGui::Render();
ImDrawData* drawData = ImGui::GetDrawData();
ImGui_ImplMetal_RenderDrawData(drawData, commandBuffer, renderEncoder);
ImDrawData* draw_data = ImGui::GetDrawData();
ImGui_ImplMetal_RenderDrawData(draw_data, commandBuffer, renderEncoder);
[renderEncoder popDebugGroup];
[renderEncoder endEncoding];
@ -316,8 +329,10 @@
@implementation AppDelegate
- (instancetype)init {
if (self = [super init]) {
- (instancetype)init
{
if (self = [super init])
{
NSViewController *rootViewController = [[ViewController alloc] initWithNibName:nil bundle:nil];
self.window = [[NSWindow alloc] initWithContentRect:NSZeroRect
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable
@ -331,7 +346,8 @@
return self;
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
{
return YES;
}
@ -363,14 +379,17 @@
#if TARGET_OS_OSX
int main(int argc, const char * argv[]) {
int main(int argc, const char * argv[])
{
return NSApplicationMain(argc, argv);
}
#else
int main(int argc, char * argv[]) {
@autoreleasepool {
int main(int argc, char * argv[])
{
@autoreleasepool
{
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

@ -139,7 +139,7 @@
animationTimer = nil;
}
// Forward Mouse/Keyboard events to dear imgui OSX backend. It returns true when imgui is expecting to use the event.
// Forward Mouse/Keyboard events to Dear ImGui OSX backend.
-(void)keyUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)keyDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)flagsChanged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }

@ -382,6 +382,7 @@ CODE
- 2020/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
- 2020/11/03 (1.80) - renamed io.ConfigWindowsMemoryCompactTimer to io.ConfigMemoryCompactTimer as the feature will apply to other data structures
- 2020/10/14 (1.80) - backends: moved all backends files (imgui_impl_XXXX.cpp, imgui_impl_XXXX.h) from examples/ to backends/.
- 2020/10/12 (1.80) - removed redirecting functions/enums that were marked obsolete in 1.60 (April 2018):
- io.RenderDrawListsFn pointer -> use ImGui::GetDrawData() value and call the render function of your backend
@ -873,6 +874,7 @@ static float NavUpdatePageUpPageDown();
static inline void NavUpdateAnyRequestFlag();
static void NavEndFrame();
static bool NavScoreItem(ImGuiNavMoveResult* result, ImRect cand);
static void NavApplyItemToResult(ImGuiNavMoveResult* result, ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb_rel);
static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, ImGuiID id);
static ImVec2 NavCalcPreferredRefPos();
static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
@ -1076,7 +1078,7 @@ ImGuiIO::ImGuiIO()
ConfigInputTextCursorBlink = true;
ConfigWindowsResizeFromEdges = true;
ConfigWindowsMoveFromTitleBarOnly = false;
ConfigWindowsMemoryCompactTimer = 60.0f;
ConfigMemoryCompactTimer = 60.0f;
// Platform Functions
BackendPlatformName = BackendRendererName = NULL;
@ -1590,66 +1592,58 @@ void* ImFileLoadToMemory(const char* filename, const char* mode, size_t* out_f
//-----------------------------------------------------------------------------
// Convert UTF-8 to 32-bit character, process single character input.
// Based on stb_from_utf8() from github.com/nothings/stb/
// A nearly-branchless UTF-8 decoder, based on work of Christopher Wellons (https://github.com/skeeto/branchless-utf8).
// We handle UTF-8 decoding error by skipping forward.
int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end)
{
unsigned int c = (unsigned int)-1;
const unsigned char* str = (const unsigned char*)in_text;
if (!(*str & 0x80))
{
c = (unsigned int)(*str++);
*out_char = c;
return 1;
}
if ((*str & 0xe0) == 0xc0)
{
*out_char = IM_UNICODE_CODEPOINT_INVALID; // will be invalid but not end of string
if (in_text_end && in_text_end - (const char*)str < 2) return 1;
if (*str < 0xc2) return 2;
c = (unsigned int)((*str++ & 0x1f) << 6);
if ((*str & 0xc0) != 0x80) return 2;
c += (*str++ & 0x3f);
*out_char = c;
return 2;
}
if ((*str & 0xf0) == 0xe0)
{
*out_char = IM_UNICODE_CODEPOINT_INVALID; // will be invalid but not end of string
if (in_text_end && in_text_end - (const char*)str < 3) return 1;
if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return 3;
if (*str == 0xed && str[1] > 0x9f) return 3; // str[1] < 0x80 is checked below
c = (unsigned int)((*str++ & 0x0f) << 12);
if ((*str & 0xc0) != 0x80) return 3;
c += (unsigned int)((*str++ & 0x3f) << 6);
if ((*str & 0xc0) != 0x80) return 3;
c += (*str++ & 0x3f);
*out_char = c;
return 3;
}
if ((*str & 0xf8) == 0xf0)
{
*out_char = IM_UNICODE_CODEPOINT_INVALID; // will be invalid but not end of string
if (in_text_end && in_text_end - (const char*)str < 4) return 1;
if (*str > 0xf4) return 4;
if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return 4;
if (*str == 0xf4 && str[1] > 0x8f) return 4; // str[1] < 0x80 is checked below
c = (unsigned int)((*str++ & 0x07) << 18);
if ((*str & 0xc0) != 0x80) return 4;
c += (unsigned int)((*str++ & 0x3f) << 12);
if ((*str & 0xc0) != 0x80) return 4;
c += (unsigned int)((*str++ & 0x3f) << 6);
if ((*str & 0xc0) != 0x80) return 4;
c += (*str++ & 0x3f);
// utf-8 encodings of values used in surrogate pairs are invalid
if ((c & 0xFFFFF800) == 0xD800) return 4;
// If codepoint does not fit in ImWchar, use replacement character U+FFFD instead
if (c > IM_UNICODE_CODEPOINT_MAX) c = IM_UNICODE_CODEPOINT_INVALID;
*out_char = c;
return 4;
}
*out_char = 0;
return 0;
static const char lengths[32] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 0 };
static const int masks[] = { 0x00, 0x7f, 0x1f, 0x0f, 0x07 };
static const uint32_t mins[] = { 0x400000, 0, 0x80, 0x800, 0x10000 };
static const int shiftc[] = { 0, 18, 12, 6, 0 };
static const int shifte[] = { 0, 6, 4, 2, 0 };
int len = lengths[*(const unsigned char*)in_text >> 3];
int wanted = len + !len;
if (in_text_end == NULL)
in_text_end = in_text + wanted; // Max length, nulls will be taken into account.
// Copy at most 'len' bytes, stop copying at 0 or past in_text_end. Branch predictor does a good job here,
// so it is fast even with excessive branching.
unsigned char s[4];
s[0] = in_text + 0 < in_text_end ? in_text[0] : 0;
s[1] = in_text + 1 < in_text_end ? in_text[1] : 0;
s[2] = in_text + 2 < in_text_end ? in_text[2] : 0;
s[3] = in_text + 3 < in_text_end ? in_text[3] : 0;
// Assume a four-byte character and load four bytes. Unused bits are shifted out.
*out_char = (uint32_t)(s[0] & masks[len]) << 18;
*out_char |= (uint32_t)(s[1] & 0x3f) << 12;
*out_char |= (uint32_t)(s[2] & 0x3f) << 6;
*out_char |= (uint32_t)(s[3] & 0x3f) << 0;
*out_char >>= shiftc[len];
// Accumulate the various error conditions.
int e = 0;
e = (*out_char < mins[len]) << 6; // non-canonical encoding
e |= ((*out_char >> 11) == 0x1b) << 7; // surrogate half?
e |= (*out_char > IM_UNICODE_CODEPOINT_MAX) << 8; // out of range?
e |= (s[1] & 0xc0) >> 2;
e |= (s[2] & 0xc0) >> 4;
e |= (s[3] ) >> 6;
e ^= 0x2a; // top two bits of each tail byte correct?
e >>= shifte[len];
if (e)
{
// No bytes are consumed when *in_text == 0 || in_text == in_text_end.
// One byte is consumed in case of invalid first byte of in_text.
// All available bytes (at most `len` bytes) are consumed on incomplete/invalid second to last bytes.
// Invalid or incomplete input may consume less bytes than wanted, therefore every byte has to be inspected in s.
wanted = ImMin(wanted, !!s[0] + !!s[1] + !!s[2] + !!s[3]);
*out_char = IM_UNICODE_CODEPOINT_INVALID;
}
return wanted;
}
int ImTextStrFromUtf8(ImWchar* buf, int buf_size, const char* in_text, const char* in_text_end, const char** in_text_remaining)
@ -4072,7 +4066,7 @@ void ImGui::NewFrame()
// Mark all windows as not visible and compact unused memory.
IM_ASSERT(g.WindowsFocusOrder.Size == g.Windows.Size);
const float memory_compact_start_time = (g.IO.ConfigWindowsMemoryCompactTimer >= 0.0f) ? (float)g.Time - g.IO.ConfigWindowsMemoryCompactTimer : FLT_MAX;
const float memory_compact_start_time = (g.IO.ConfigMemoryCompactTimer >= 0.0f) ? (float)g.Time - g.IO.ConfigMemoryCompactTimer : FLT_MAX;
for (int i = 0; i != g.Windows.Size; i++)
{
ImGuiWindow* window = g.Windows[i];
@ -9121,6 +9115,14 @@ static bool ImGui::NavScoreItem(ImGuiNavMoveResult* result, ImRect cand)
return new_best;
}
static void ImGui::NavApplyItemToResult(ImGuiNavMoveResult* result, ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb_rel)
{
result->Window = window;
result->ID = id;
result->FocusScopeId = window->DC.NavFocusScopeIdCurrent;
result->RectRel = nav_bb_rel;
}
// We get there when either NavId == id, or when g.NavAnyRequest is set (which is updated by NavUpdateAnyRequestFlag above)
static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, const ImGuiID id)
{
@ -9161,25 +9163,14 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con
bool new_best = g.NavMoveRequest && NavScoreItem(result, nav_bb);
#endif
if (new_best)
{
result->Window = window;
result->ID = id;
result->FocusScopeId = window->DC.NavFocusScopeIdCurrent;
result->RectRel = nav_bb_rel;
}
NavApplyItemToResult(result, window, id, nav_bb_rel);
// Features like PageUp/PageDown need to maintain a separate score for the visible set of items.
const float VISIBLE_RATIO = 0.70f;
if ((g.NavMoveRequestFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) && window->ClipRect.Overlaps(nav_bb))
if (ImClamp(nav_bb.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y) - ImClamp(nav_bb.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO)
if (NavScoreItem(&g.NavMoveResultLocalVisibleSet, nav_bb))
{
result = &g.NavMoveResultLocalVisibleSet;
result->Window = window;
result->ID = id;
result->FocusScopeId = window->DC.NavFocusScopeIdCurrent;
result->RectRel = nav_bb_rel;
}
NavApplyItemToResult(&g.NavMoveResultLocalVisibleSet, window, id, nav_bb_rel);
}
// Update window-relative bounding box of navigated item
@ -15629,7 +15620,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
// Contents
DebugNodeWindowsList(&g.Windows, "Windows");
//DebugNodeWindowsList(&g.WindowsFocusOrder, "WindowsFocusOrder");
if (TreeNode("Viewport", "Viewports (%d)", g.Viewports.Size))
if (TreeNode("Viewports", "Viewports (%d)", g.Viewports.Size))
{
Indent(GetTreeNodeToLabelSpacing());
RenderViewportsThumbnails();
@ -15916,15 +15907,15 @@ void ImGui::DebugNodeDockNode(ImGuiDockNode* node, const char* label)
node->WantLockSizeOnce ? " WantLockSizeOnce" : "");
if (TreeNode("flags", "LocalFlags: 0x%04X SharedFlags: 0x%04X", node->LocalFlags, node->SharedFlags))
{
CheckboxFlags("LocalFlags: NoDocking", (ImU32*)&node->LocalFlags, ImGuiDockNodeFlags_NoDocking);
CheckboxFlags("LocalFlags: NoSplit", (ImU32*)&node->LocalFlags, ImGuiDockNodeFlags_NoSplit);
CheckboxFlags("LocalFlags: NoResize", (ImU32*)&node->LocalFlags, ImGuiDockNodeFlags_NoResize);
CheckboxFlags("LocalFlags: NoResizeX", (ImU32*)&node->LocalFlags, ImGuiDockNodeFlags_NoResizeX);
CheckboxFlags("LocalFlags: NoResizeY", (ImU32*)&node->LocalFlags, ImGuiDockNodeFlags_NoResizeY);
CheckboxFlags("LocalFlags: NoTabBar", (ImU32*)&node->LocalFlags, ImGuiDockNodeFlags_NoTabBar);
CheckboxFlags("LocalFlags: HiddenTabBar", (ImU32*)&node->LocalFlags, ImGuiDockNodeFlags_HiddenTabBar);
CheckboxFlags("LocalFlags: NoWindowMenuButton", (ImU32*)&node->LocalFlags, ImGuiDockNodeFlags_NoWindowMenuButton);
CheckboxFlags("LocalFlags: NoCloseButton", (ImU32*)&node->LocalFlags, ImGuiDockNodeFlags_NoCloseButton);
CheckboxFlags("LocalFlags: NoDocking", &node->LocalFlags, ImGuiDockNodeFlags_NoDocking);
CheckboxFlags("LocalFlags: NoSplit", &node->LocalFlags, ImGuiDockNodeFlags_NoSplit);
CheckboxFlags("LocalFlags: NoResize", &node->LocalFlags, ImGuiDockNodeFlags_NoResize);
CheckboxFlags("LocalFlags: NoResizeX", &node->LocalFlags, ImGuiDockNodeFlags_NoResizeX);
CheckboxFlags("LocalFlags: NoResizeY", &node->LocalFlags, ImGuiDockNodeFlags_NoResizeY);
CheckboxFlags("LocalFlags: NoTabBar", &node->LocalFlags, ImGuiDockNodeFlags_NoTabBar);
CheckboxFlags("LocalFlags: HiddenTabBar", &node->LocalFlags, ImGuiDockNodeFlags_HiddenTabBar);
CheckboxFlags("LocalFlags: NoWindowMenuButton", &node->LocalFlags, ImGuiDockNodeFlags_NoWindowMenuButton);
CheckboxFlags("LocalFlags: NoCloseButton", &node->LocalFlags, ImGuiDockNodeFlags_NoCloseButton);
TreePop();
}
if (node->ParentNode)
@ -16224,7 +16215,7 @@ void ImGui::DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* la
void ImGui::ShowMetricsWindow(bool*) {}
void ImGui::DebugNodeColumns(ImGuiColumns*) {}
void ImGui::DebugNodeDrawList(ImGuiWindow*, ImGuiViewportP* viewport, const ImDrawList*, const char*) {}
void ImGui::DebugNodeDrawList(ImGuiWindow*, ImGuiViewportP*, const ImDrawList*, const char*) {}
void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList*, const ImDrawList*, const ImDrawCmd*, bool, bool) {}
void ImGui::DebugNodeStorage(ImGuiStorage*, const char*) {}
void ImGui::DebugNodeTabBar(ImGuiTabBar*, const char*) {}

@ -61,7 +61,7 @@ Index of this file:
// 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)
#define IMGUI_VERSION "1.80 WIP"
#define IMGUI_VERSION_NUM 17905
#define IMGUI_VERSION_NUM 17906
#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_DOCK 1 // Docking WIP branch
@ -456,6 +456,7 @@ namespace ImGui
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0));
IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding
IMGUI_API bool Checkbox(const char* label, bool* v);
IMGUI_API bool CheckboxFlags(const char* label, int* flags, int flags_value);
IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
IMGUI_API bool RadioButton(const char* label, bool active); // use with e.g. if (RadioButton("one", my_value==1)) { my_value = 1; }
IMGUI_API bool RadioButton(const char* label, int* v, int v_button); // shortcut to handle the above pattern when value is an integer
@ -1611,7 +1612,7 @@ struct ImGuiIO
bool ConfigInputTextCursorBlink; // = true // Set to false to disable blinking cursor, for users who consider it distracting. (was called: io.OptCursorBlink prior to 1.63)
bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag)
bool ConfigWindowsMoveFromTitleBarOnly; // = false // [BETA] Set to true to only allow moving windows when clicked+dragged from the title bar. Windows without a title bar are not affected.
float ConfigWindowsMemoryCompactTimer;// = 60.0f // [BETA] Compact window memory usage when unused. Set to -1.0f to disable.
float ConfigMemoryCompactTimer; // = 60.0f // [BETA] Free transient windows/tables memory buffers when unused for given amount of time. Set to -1.0f to disable.
//------------------------------------------------------------------
// Platform Functions
@ -2110,7 +2111,15 @@ struct ImDrawVert
IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT;
#endif
// For use by ImDrawListSplitter.
// [Internal] For use by ImDrawList
struct ImDrawCmdHeader
{
ImVec4 ClipRect;
ImTextureID TextureId;
unsigned int VtxOffset;
};
// [Internal] For use by ImDrawListSplitter
struct ImDrawChannel
{
ImVector<ImDrawCmd> _CmdBuffer;
@ -2125,7 +2134,7 @@ struct ImDrawListSplitter
int _Count; // Number of active channels (1+)
ImVector<ImDrawChannel> _Channels; // Draw channels (not resized down so _Count might be < Channels.Size)
inline ImDrawListSplitter() { Clear(); }
inline ImDrawListSplitter() { memset(this, 0, sizeof(*this)); }
inline ~ImDrawListSplitter() { ClearFreeMemory(); }
inline void Clear() { _Current = 0; _Count = 1; } // Do not clear Channels[] so our allocations are reused next frame
IMGUI_API void ClearFreeMemory();
@ -2176,19 +2185,19 @@ struct ImDrawList
ImDrawListFlags Flags; // Flags, you may poke into these to adjust anti-aliasing settings per-primitive.
// [Internal, used while building lists]
unsigned int _VtxCurrentIdx; // [Internal] generally == VtxBuffer.Size unless we are past 64K vertices, in which case this gets reset to 0.
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
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)
ImDrawIdx* _IdxWritePtr; // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
ImVector<ImVec4> _ClipRectStack; // [Internal]
ImVector<ImTextureID> _TextureIdStack; // [Internal]
ImVector<ImVec2> _Path; // [Internal] current path building
ImDrawCmd _CmdHeader; // [Internal] Template of active commands. Fields should match those of CmdBuffer.back().
ImDrawCmdHeader _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)
ImDrawList(const ImDrawListSharedData* shared_data) { _Data = shared_data; Flags = ImDrawListFlags_None; _VtxCurrentIdx = 0; _VtxWritePtr = NULL; _IdxWritePtr = NULL; _OwnerName = NULL; }
ImDrawList(const ImDrawListSharedData* shared_data) { memset(this, 0, sizeof(*this)); _Data = shared_data; }
~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)

@ -398,16 +398,15 @@ void ImGui::ShowDemoWindow(bool* p_open)
if (ImGui::TreeNode("Configuration##2"))
{
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", (unsigned int*)&io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard);
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", (unsigned int*)&io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", &io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard);
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", &io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
ImGui::SameLine(); HelpMarker("Required backend to feed in gamepad inputs in io.NavInputs[] and set io.BackendFlags |= ImGuiBackendFlags_HasGamepad.\n\nRead instructions in imgui.cpp for details.");
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", (unsigned int*)&io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos);
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", &io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos);
ImGui::SameLine(); HelpMarker("Instruct navigation to move the mouse cursor. See comment for ImGuiConfigFlags_NavEnableSetMousePos.");
ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", (unsigned int*)&io.ConfigFlags, ImGuiConfigFlags_NoMouse);
// The "NoMouse" option above can get us stuck with a disable mouse! Provide an alternative way to fix it:
ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", &io.ConfigFlags, ImGuiConfigFlags_NoMouse);
if (io.ConfigFlags & ImGuiConfigFlags_NoMouse)
{
// The "NoMouse" option can get us stuck with a disabled mouse! Let's provide an alternative way to fix it:
if (fmodf((float)ImGui::GetTime(), 0.40f) < 0.20f)
{
ImGui::SameLine();
@ -416,10 +415,10 @@ void ImGui::ShowDemoWindow(bool* p_open)
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Space)))
io.ConfigFlags &= ~ImGuiConfigFlags_NoMouse;
}
ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", (unsigned int*)&io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange);
ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", &io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange);
ImGui::SameLine(); HelpMarker("Instruct backend to not alter mouse cursor shape and visibility.");
ImGui::CheckboxFlags("io.ConfigFlags: DockingEnable", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_DockingEnable);
ImGui::CheckboxFlags("io.ConfigFlags: DockingEnable", &io.ConfigFlags, ImGuiConfigFlags_DockingEnable);
ImGui::SameLine(); HelpMarker(io.ConfigDockingWithShift ? "[beta] Use SHIFT to dock window into each others." : "[beta] Drag from title bar to dock windows into each others.");
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
{
@ -435,7 +434,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::Unindent();
}
ImGui::CheckboxFlags("io.ConfigFlags: ViewportsEnable", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_ViewportsEnable);
ImGui::CheckboxFlags("io.ConfigFlags: ViewportsEnable", &io.ConfigFlags, ImGuiConfigFlags_ViewportsEnable);
ImGui::SameLine(); HelpMarker("[beta] Enable beta multi-viewports support. See ImGuiPlatformIO for details.");
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
@ -471,13 +470,13 @@ void ImGui::ShowDemoWindow(bool* p_open)
// Make a local copy to avoid modifying actual backend flags.
ImGuiBackendFlags backend_flags = io.BackendFlags;
ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", (unsigned int*)&backend_flags, ImGuiBackendFlags_HasGamepad);
ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", (unsigned int*)&backend_flags, ImGuiBackendFlags_HasMouseCursors);
ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", (unsigned int*)&backend_flags, ImGuiBackendFlags_HasSetMousePos);
ImGui::CheckboxFlags("io.BackendFlags: PlatformHasViewports", (unsigned int*)&backend_flags, ImGuiBackendFlags_PlatformHasViewports);
ImGui::CheckboxFlags("io.BackendFlags: HasMouseHoveredViewport",(unsigned int*)&backend_flags, ImGuiBackendFlags_HasMouseHoveredViewport);
ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", (unsigned int*)&backend_flags, ImGuiBackendFlags_RendererHasVtxOffset);
ImGui::CheckboxFlags("io.BackendFlags: RendererHasViewports", (unsigned int*)&backend_flags, ImGuiBackendFlags_RendererHasViewports);
ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", &backend_flags, ImGuiBackendFlags_HasGamepad);
ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", &backend_flags, ImGuiBackendFlags_HasMouseCursors);
ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", &backend_flags, ImGuiBackendFlags_HasSetMousePos);
ImGui::CheckboxFlags("io.BackendFlags: PlatformHasViewports", &backend_flags, ImGuiBackendFlags_PlatformHasViewports);
ImGui::CheckboxFlags("io.BackendFlags: HasMouseHoveredViewport",&backend_flags, ImGuiBackendFlags_HasMouseHoveredViewport);
ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &backend_flags, ImGuiBackendFlags_RendererHasVtxOffset);
ImGui::CheckboxFlags("io.BackendFlags: RendererHasViewports", &backend_flags, ImGuiBackendFlags_RendererHasViewports);
ImGui::TreePop();
ImGui::Separator();
}
@ -766,10 +765,10 @@ static void ShowDemoWindowWidgets()
static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth;
static bool align_label_with_current_x_position = false;
static bool test_drag_and_drop = false;
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_OpenOnArrow);
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick);
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node.");
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanFullWidth);
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", &base_flags, ImGuiTreeNodeFlags_OpenOnArrow);
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", &base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick);
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", &base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node.");
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &base_flags, ImGuiTreeNodeFlags_SpanFullWidth);
ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position);
ImGui::Checkbox("Test tree node as drag source", &test_drag_and_drop);
ImGui::Text("Hello!");
@ -1026,11 +1025,11 @@ static void ShowDemoWindowWidgets()
{
// Expose flags as checkbox for the demo
static ImGuiComboFlags flags = 0;
ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", (unsigned int*)&flags, ImGuiComboFlags_PopupAlignLeft);
ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", &flags, ImGuiComboFlags_PopupAlignLeft);
ImGui::SameLine(); HelpMarker("Only makes a difference if the popup is larger than the combo");
if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", (unsigned int*)&flags, ImGuiComboFlags_NoArrowButton))
if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", &flags, ImGuiComboFlags_NoArrowButton))
flags &= ~ImGuiComboFlags_NoPreview; // Clear the other flag, as we cannot combine both
if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", (unsigned int*)&flags, ImGuiComboFlags_NoPreview))
if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", &flags, ImGuiComboFlags_NoPreview))
flags &= ~ImGuiComboFlags_NoArrowButton; // Clear the other flag, as we cannot combine both
// Using the generic BeginCombo() API, you have full control over how to display the combo contents.
@ -1221,9 +1220,9 @@ static void ShowDemoWindowWidgets()
static ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput;
HelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp because we don't want to include <string> in here)");
ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", (unsigned int*)&flags, ImGuiInputTextFlags_ReadOnly);
ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", (unsigned int*)&flags, ImGuiInputTextFlags_AllowTabInput);
ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", (unsigned int*)&flags, ImGuiInputTextFlags_CtrlEnterForNewLine);
ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly);
ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", &flags, ImGuiInputTextFlags_AllowTabInput);
ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", &flags, ImGuiInputTextFlags_CtrlEnterForNewLine);
ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16), flags);
ImGui::TreePop();
}
@ -1621,13 +1620,13 @@ static void ShowDemoWindowWidgets()
{
// Demonstrate using advanced flags for DragXXX and SliderXXX functions. Note that the flags are the same!
static ImGuiSliderFlags flags = ImGuiSliderFlags_None;
ImGui::CheckboxFlags("ImGuiSliderFlags_AlwaysClamp", (unsigned int*)&flags, ImGuiSliderFlags_AlwaysClamp);
ImGui::CheckboxFlags("ImGuiSliderFlags_AlwaysClamp", &flags, ImGuiSliderFlags_AlwaysClamp);
ImGui::SameLine(); HelpMarker("Always clamp value to min/max bounds (if any) when input manually with CTRL+Click.");
ImGui::CheckboxFlags("ImGuiSliderFlags_Logarithmic", (unsigned int*)&flags, ImGuiSliderFlags_Logarithmic);
ImGui::CheckboxFlags("ImGuiSliderFlags_Logarithmic", &flags, ImGuiSliderFlags_Logarithmic);
ImGui::SameLine(); HelpMarker("Enable logarithmic editing (more precision for small values).");
ImGui::CheckboxFlags("ImGuiSliderFlags_NoRoundToFormat", (unsigned int*)&flags, ImGuiSliderFlags_NoRoundToFormat);
ImGui::CheckboxFlags("ImGuiSliderFlags_NoRoundToFormat", &flags, ImGuiSliderFlags_NoRoundToFormat);
ImGui::SameLine(); HelpMarker("Disable rounding underlying value to match precision of the format string (e.g. %.3f values are rounded to those 3 digits).");
ImGui::CheckboxFlags("ImGuiSliderFlags_NoInput", (unsigned int*)&flags, ImGuiSliderFlags_NoInput);
ImGui::CheckboxFlags("ImGuiSliderFlags_NoInput", &flags, ImGuiSliderFlags_NoInput);
ImGui::SameLine(); HelpMarker("Disable CTRL+Click or Enter key allowing to input text directly into the widget.");
// Drags
@ -2383,15 +2382,15 @@ static void ShowDemoWindowLayout()
{
// Expose a couple of the available flags. In most cases you may just call BeginTabBar() with no flags (0).
static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable;
ImGui::CheckboxFlags("ImGuiTabBarFlags_Reorderable", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_Reorderable);
ImGui::CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_AutoSelectNewTabs);
ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton);
ImGui::CheckboxFlags("ImGuiTabBarFlags_Reorderable", &tab_bar_flags, ImGuiTabBarFlags_Reorderable);
ImGui::CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", &tab_bar_flags, ImGuiTabBarFlags_AutoSelectNewTabs);
ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", &tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton);
if ((tab_bar_flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0)
tab_bar_flags |= ImGuiTabBarFlags_FittingPolicyDefault_;
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
// Tab Bar
@ -2439,10 +2438,10 @@ static void ShowDemoWindowLayout()
// Expose some other flags which are useful to showcase how they interact with Leading/Trailing tabs
static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyResizeDown;
ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
@ -3766,7 +3765,7 @@ void ImGui::ShowAboutWindow(bool* p_open)
if (io.ConfigInputTextCursorBlink) ImGui::Text("io.ConfigInputTextCursorBlink");
if (io.ConfigWindowsResizeFromEdges) ImGui::Text("io.ConfigWindowsResizeFromEdges");
if (io.ConfigWindowsMoveFromTitleBarOnly) ImGui::Text("io.ConfigWindowsMoveFromTitleBarOnly");
if (io.ConfigWindowsMemoryCompactTimer >= 0.0f) ImGui::Text("io.ConfigWindowsMemoryCompactTimer = %.1ff", io.ConfigWindowsMemoryCompactTimer);
if (io.ConfigMemoryCompactTimer >= 0.0f) ImGui::Text("io.ConfigMemoryCompactTimer = %.1f", io.ConfigMemoryCompactTimer);
ImGui::Text("io.BackendFlags: 0x%08X", io.BackendFlags);
if (io.BackendFlags & ImGuiBackendFlags_HasGamepad) ImGui::Text(" HasGamepad");
if (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) ImGui::Text(" HasMouseCursors");

@ -350,21 +350,12 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
ImDrawListSharedData::ImDrawListSharedData()
{
Font = NULL;
FontSize = 0.0f;
CurveTessellationTol = 0.0f;
CircleSegmentMaxError = 0.0f;
ClipRectFullscreen = ImVec4(-8192.0f, -8192.0f, +8192.0f, +8192.0f);
InitialFlags = ImDrawListFlags_None;
// Lookup tables
memset(this, 0, sizeof(*this));
for (int i = 0; i < IM_ARRAYSIZE(ArcFastVtx); i++)
{
const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(ArcFastVtx);
ArcFastVtx[i] = ImVec2(ImCos(a), ImSin(a));
}
memset(CircleSegmentCounts, 0, sizeof(CircleSegmentCounts)); // This will be set by SetCircleSegmentMaxError()
TexUvLines = NULL;
}
void ImDrawListSharedData::SetCircleSegmentMaxError(float max_error)
@ -1435,7 +1426,10 @@ void ImDrawListSplitter::Split(ImDrawList* draw_list, int channels_count)
IM_ASSERT(_Current == 0 && _Count <= 1 && "Nested channel splitting is not supported. Please use separate instances of ImDrawListSplitter.");
int old_channels_count = _Channels.Size;
if (old_channels_count < channels_count)
{
_Channels.reserve(channels_count); // Avoid over reserving since this is likely to stay stable
_Channels.resize(channels_count);
}
_Count = channels_count;
// Channels[] (24/32 bytes each) hold storage that we'll swap with draw_list->_CmdBuffer/_IdxBuffer

@ -856,7 +856,7 @@ struct IMGUI_API ImGuiMenuColumns
float Width, NextWidth;
float Pos[3], NextWidths[3];
ImGuiMenuColumns();
ImGuiMenuColumns() { memset(this, 0, sizeof(*this)); }
void Update(int count, float spacing, bool clear);
float DeclColumns(float w0, float w1, float w2);
float CalcExtraSpace(float avail_w) const;
@ -909,7 +909,7 @@ struct ImGuiPopupData
ImVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse)
ImVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup
ImGuiPopupData() { PopupId = 0; Window = SourceWindow = NULL; OpenFrameCount = -1; OpenParentId = 0; }
ImGuiPopupData() { memset(this, 0, sizeof(*this)); OpenFrameCount = -1; }
};
struct ImGuiNavMoveResult
@ -1026,7 +1026,7 @@ struct ImGuiColumnData
ImGuiColumnsFlags Flags; // Not exposed
ImRect ClipRect;
ImGuiColumnData() { OffsetNorm = OffsetNormBeforeResize = 0.0f; Flags = ImGuiColumnsFlags_None; }
ImGuiColumnData() { memset(this, 0, sizeof(*this)); }
};
struct ImGuiColumns
@ -1047,21 +1047,7 @@ struct ImGuiColumns
ImVector<ImGuiColumnData> Columns;
ImDrawListSplitter Splitter;
ImGuiColumns() { Clear(); }
void Clear()
{
ID = 0;
Flags = ImGuiColumnsFlags_None;
IsFirstFrame = false;
IsBeingResized = false;
Current = 0;
Count = 1;
OffMinX = OffMaxX = 0.0f;
LineMinY = LineMaxY = 0.0f;
HostCursorPosY = 0.0f;
HostCursorMaxPosX = 0.0f;
Columns.clear();
}
ImGuiColumns() { memset(this, 0, sizeof(*this)); }
};
//-----------------------------------------------------------------------------
@ -1124,6 +1110,7 @@ struct ImGuiDockNode
ImGuiID ID;
ImGuiDockNodeFlags SharedFlags; // Flags shared by all nodes of a same dockspace hierarchy (inherited from the root node)
ImGuiDockNodeFlags LocalFlags; // Flags specific to this node
ImGuiDockNodeState State;
ImGuiDockNode* ParentNode;
ImGuiDockNode* ChildNodes[2]; // [Split node only] Child nodes (left/right or top/bottom). Consider switching to an array.
ImVector<ImGuiWindow*> Windows; // Note: unordered list! Iterate TabBar->Tabs for user-order.
@ -1134,7 +1121,6 @@ struct ImGuiDockNode
ImGuiAxis SplitAxis; // [Split node only] Split axis (X or Y)
ImGuiWindowClass WindowClass; // [Root node only]
ImGuiDockNodeState State;
ImGuiWindow* HostWindow;
ImGuiWindow* VisibleWindow; // Generally point to window which is ID is == SelectedTabID, but when CTRL+Tabbing this can be a different window.
ImGuiDockNode* CentralNode; // [Root node only] Pointer to central node.
@ -1245,7 +1231,7 @@ struct ImGuiWindowSettings
bool Collapsed;
bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context)
ImGuiWindowSettings() { ID = 0; Pos = Size = ViewportPos = ImVec2ih(0, 0); ViewportId = DockId = ClassId = 0; DockOrder = -1; Collapsed = WantApply = false; }
ImGuiWindowSettings() { memset(this, 0, sizeof(*this)); DockOrder = -1; }
char* GetName() { return (char*)(this + 1); }
};
@ -1886,9 +1872,9 @@ struct IMGUI_API ImGuiWindow
ImGuiID NavLastIds[ImGuiNavLayer_COUNT]; // Last known NavId for this window, per layer (0/1)
ImRect NavRectRel[ImGuiNavLayer_COUNT]; // Reference rectangle, in window relative space
bool MemoryCompacted; // Set when window extraneous data have been garbage collected
int MemoryDrawListIdxCapacity; // Backup of last idx/vtx count, so when waking up the window we can preallocate and avoid iterative alloc/copy
int MemoryDrawListVtxCapacity;
bool MemoryCompacted; // Set when window extraneous data have been garbage collected
// Docking
ImGuiDockNode* DockNode; // Which node are we docked into. Important: Prefer testing DockIsActive in many cases as this will still be set when the dock node is hidden.
@ -2325,6 +2311,7 @@ namespace ImGui
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool DragBehaviorT(ImGuiDataType data_type, T* v, float v_speed, T v_min, T v_max, const char* format, ImGuiSliderFlags flags);
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, T* v, T v_min, T v_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb);
template<typename T, typename SIGNED_T> IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v);
template<typename T> IMGUI_API bool CheckboxFlagsT(const char* label, T* flags, T flags_value);
// Data type helpers
IMGUI_API const ImGuiDataTypeInfo* DataTypeGetInfo(ImGuiDataType data_type);

@ -408,6 +408,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
// - Image()
// - ImageButton()
// - Checkbox()
// - CheckboxFlagsT() [Internal]
// - CheckboxFlags()
// - RadioButton()
// - ProgressBar()
@ -1082,6 +1083,7 @@ bool ImGui::Checkbox(const char* label, bool* v)
if (mixed_value)
{
// Undocumented tristate/mixed/indeterminate checkbox (#2644)
// This may seem awkwardly designed because the aim is to make ImGuiItemFlags_MixedValue supported by all widgets (not just checkbox)
ImVec2 pad(ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)), ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)));
window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding);
}
@ -1100,35 +1102,45 @@ bool ImGui::Checkbox(const char* label, bool* v)
return pressed;
}
bool ImGui::CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value)
template<typename T>
bool ImGui::CheckboxFlagsT(const char* label, T* flags, T flags_value)
{
bool v = ((*flags & flags_value) == flags_value);
bool all_on = (*flags & flags_value) == flags_value;
bool any_on = (*flags & flags_value) != 0;
bool pressed;
if (v == false && (*flags & flags_value) != 0)
if (!all_on && any_on)
{
// Mixed value (FIXME: find a way to expose neatly to Checkbox?)
ImGuiWindow* window = GetCurrentWindow();
const ImGuiItemFlags backup_item_flags = window->DC.ItemFlags;
ImGuiItemFlags backup_item_flags = window->DC.ItemFlags;
window->DC.ItemFlags |= ImGuiItemFlags_MixedValue;
pressed = Checkbox(label, &v);
pressed = Checkbox(label, &all_on);
window->DC.ItemFlags = backup_item_flags;
}
else
{
// Regular checkbox
pressed = Checkbox(label, &v);
pressed = Checkbox(label, &all_on);
}
if (pressed)
{
if (v)
if (all_on)
*flags |= flags_value;
else
*flags &= ~flags_value;
}
return pressed;
}
bool ImGui::CheckboxFlags(const char* label, int* flags, int flags_value)
{
return CheckboxFlagsT(label, flags, flags_value);
}
bool ImGui::CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value)
{
return CheckboxFlagsT(label, flags, flags_value);
}
bool ImGui::RadioButton(const char* label, bool active)
{
ImGuiWindow* window = GetCurrentWindow();
@ -5444,7 +5456,7 @@ void ImGui::ColorPickerOptionsPopup(const float* ref_col, ImGuiColorEditFlags fl
if (allow_opt_alpha_bar)
{
if (allow_opt_picker) Separator();
CheckboxFlags("Alpha Bar", (unsigned int*)&g.ColorEditOptions, ImGuiColorEditFlags_AlphaBar);
CheckboxFlags("Alpha Bar", &g.ColorEditOptions, ImGuiColorEditFlags_AlphaBar);
}
EndPopup();
}
@ -5919,10 +5931,6 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const bool span_all_columns = (flags & ImGuiSelectableFlags_SpanAllColumns) != 0;
if (span_all_columns && window->DC.CurrentColumns) // FIXME-OPT: Avoid if vertically clipped.
PushColumnsBackground();
// Submit label or explicit size to ItemSize(), whereas ItemAdd() will submit a larger/spanning rectangle.
ImGuiID id = window->GetID(label);
ImVec2 label_size = CalcTextSize(label, NULL, true);
@ -5933,6 +5941,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
// Fill horizontal space
// We don't support (size < 0.0f) in Selectable() because the ItemSpacing extension would make explicitely right-aligned sizes not visibly match other widgets.
const bool span_all_columns = (flags & ImGuiSelectableFlags_SpanAllColumns) != 0;
const float min_x = span_all_columns ? window->ParentWorkRect.Min.x : pos.x;
const float max_x = span_all_columns ? window->ParentWorkRect.Max.x : window->WorkRect.Max.x;
if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_SpanAvailWidth))
@ -5957,6 +5966,15 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
}
//if (g.IO.KeyCtrl) { GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(0, 255, 0, 255)); }
// Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackground for every Selectable..
const float backup_clip_rect_min_x = window->ClipRect.Min.x;
const float backup_clip_rect_max_x = window->ClipRect.Max.x;
if (span_all_columns)
{
window->ClipRect.Min.x = window->ParentWorkRect.Min.x;
window->ClipRect.Max.x = window->ParentWorkRect.Max.x;
}
bool item_add;
if (flags & ImGuiSelectableFlags_Disabled)
{
@ -5969,13 +5987,21 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
{
item_add = ItemAdd(bb, id);
}
if (!item_add)
if (span_all_columns)
{
if (span_all_columns && window->DC.CurrentColumns)
PopColumnsBackground();
return false;
window->ClipRect.Min.x = backup_clip_rect_min_x;
window->ClipRect.Max.x = backup_clip_rect_max_x;
}
if (!item_add)
return false;
// FIXME: We can standardize the behavior of those two, we could also keep the fast path of override ClipRect + full push on render only,
// which would be advantageous since most selectable are not selected.
if (span_all_columns && window->DC.CurrentColumns)
PushColumnsBackground();
// We use NoHoldingActiveID on menus so user can click and _hold_ on a menu then drag to browse child entries
ImGuiButtonFlags button_flags = 0;
if (flags & ImGuiSelectableFlags_NoHoldingActiveID) { button_flags |= ImGuiButtonFlags_NoHoldingActiveId; }
@ -6384,13 +6410,6 @@ void ImGui::Value(const char* prefix, float v, const char* float_format)
//-------------------------------------------------------------------------
// Helpers for internal use
ImGuiMenuColumns::ImGuiMenuColumns()
{
Spacing = Width = NextWidth = 0.0f;
memset(Pos, 0, sizeof(Pos));
memset(NextWidths, 0, sizeof(NextWidths));
}
void ImGuiMenuColumns::Update(int count, float spacing, bool clear)
{
IM_ASSERT(count == IM_ARRAYSIZE(Pos));

Loading…
Cancel
Save