mirror of
https://github.com/ocornut/imgui.git
synced 2025-10-17 23:41:45 +00:00
Merge branch 'master' into docking
# Conflicts: # backends/imgui_impl_glfw.cpp # imgui.cpp
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
|
// 2022-04-30: Inputs: Fixed ImGui_ImplGlfw_TranslateUntranslatedKey() for lower case letters on OSX.
|
||||||
// 2022-03-23: Inputs: Fixed a regression in 1.87 which resulted in keyboard modifiers events being reported incorrectly on Linux/X11.
|
// 2022-03-23: Inputs: Fixed a regression in 1.87 which resulted in keyboard modifiers events being reported incorrectly on Linux/X11.
|
||||||
// 2022-02-07: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing callbacks after initializing backend.
|
// 2022-02-07: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing callbacks after initializing backend.
|
||||||
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
|
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
|
||||||
@@ -334,6 +335,7 @@ static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode)
|
|||||||
IM_ASSERT(IM_ARRAYSIZE(char_names) == IM_ARRAYSIZE(char_keys));
|
IM_ASSERT(IM_ARRAYSIZE(char_names) == IM_ARRAYSIZE(char_keys));
|
||||||
if (key_name[0] >= '0' && key_name[0] <= '9') { key = GLFW_KEY_0 + (key_name[0] - '0'); }
|
if (key_name[0] >= '0' && key_name[0] <= '9') { key = GLFW_KEY_0 + (key_name[0] - '0'); }
|
||||||
else if (key_name[0] >= 'A' && key_name[0] <= 'Z') { key = GLFW_KEY_A + (key_name[0] - 'A'); }
|
else if (key_name[0] >= 'A' && key_name[0] <= 'Z') { key = GLFW_KEY_A + (key_name[0] - 'A'); }
|
||||||
|
else if (key_name[0] >= 'a' && key_name[0] <= 'z') { key = GLFW_KEY_A + (key_name[0] - 'a'); }
|
||||||
else if (const char* p = strchr(char_names, key_name[0])) { key = char_keys[p - char_names]; }
|
else if (const char* p = strchr(char_names, key_name[0])) { key = char_keys[p - char_names]; }
|
||||||
}
|
}
|
||||||
// if (action == GLFW_PRESS) printf("key %d scancode %d name '%s'\n", key, scancode, key_name);
|
// if (action == GLFW_PRESS) printf("key %d scancode %d name '%s'\n", key, scancode, key_name);
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2022-04-27: Misc: Store backend data in a per-context struct, allowing to use this backend with multiple contexts.
|
||||||
// 2022-01-03: Metal: Ignore ImDrawCmd where ElemCount == 0 (very rare but can technically be manufactured by user code).
|
// 2022-01-03: Metal: Ignore ImDrawCmd where ElemCount == 0 (very rare but can technically be manufactured by user code).
|
||||||
// 2021-12-30: Metal: Added Metal C++ support. Enable with '#define IMGUI_IMPL_METAL_CPP' in your imconfig.h file.
|
// 2021-12-30: Metal: Added Metal C++ support. Enable with '#define IMGUI_IMPL_METAL_CPP' in your imconfig.h file.
|
||||||
// 2021-08-24: Metal: Fixed a crash when clipping rect larger than framebuffer is submitted. (#4464)
|
// 2021-08-24: Metal: Fixed a crash when clipping rect larger than framebuffer is submitted. (#4464)
|
||||||
@@ -28,17 +29,15 @@
|
|||||||
|
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include "imgui_impl_metal.h"
|
#include "imgui_impl_metal.h"
|
||||||
|
#import <time.h>
|
||||||
#import <Metal/Metal.h>
|
#import <Metal/Metal.h>
|
||||||
// #import <QuartzCore/CAMetalLayer.h> // Not supported in XCode 9.2. Maybe a macro to detect the SDK version can be used (something like #if MACOS_SDK >= 10.13 ...)
|
|
||||||
#import <simd/simd.h>
|
|
||||||
|
|
||||||
#pragma mark - Support classes
|
#pragma mark - Support classes
|
||||||
|
|
||||||
// A wrapper around a MTLBuffer object that knows the last time it was reused
|
// A wrapper around a MTLBuffer object that knows the last time it was reused
|
||||||
@interface MetalBuffer : NSObject
|
@interface MetalBuffer : NSObject
|
||||||
@property (nonatomic, strong) id<MTLBuffer> buffer;
|
@property (nonatomic, strong) id<MTLBuffer> buffer;
|
||||||
@property (nonatomic, assign) NSTimeInterval lastReuseTime;
|
@property (nonatomic, assign) double lastReuseTime;
|
||||||
- (instancetype)initWithBuffer:(id<MTLBuffer>)buffer;
|
- (instancetype)initWithBuffer:(id<MTLBuffer>)buffer;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -56,12 +55,13 @@
|
|||||||
// renderer backend. Stores the render pipeline state cache and the default
|
// renderer backend. Stores the render pipeline state cache and the default
|
||||||
// font texture, and manages the reusable buffer cache.
|
// font texture, and manages the reusable buffer cache.
|
||||||
@interface MetalContext : NSObject
|
@interface MetalContext : NSObject
|
||||||
|
@property (nonatomic, strong) id<MTLDevice> device;
|
||||||
@property (nonatomic, strong) id<MTLDepthStencilState> depthStencilState;
|
@property (nonatomic, strong) id<MTLDepthStencilState> depthStencilState;
|
||||||
@property (nonatomic, strong) FramebufferDescriptor *framebufferDescriptor; // framebuffer descriptor for current frame; transient
|
@property (nonatomic, strong) FramebufferDescriptor *framebufferDescriptor; // framebuffer descriptor for current frame; transient
|
||||||
@property (nonatomic, strong) NSMutableDictionary *renderPipelineStateCache; // pipeline cache; keyed on framebuffer descriptors
|
@property (nonatomic, strong) NSMutableDictionary *renderPipelineStateCache; // pipeline cache; keyed on framebuffer descriptors
|
||||||
@property (nonatomic, strong, nullable) id<MTLTexture> fontTexture;
|
@property (nonatomic, strong, nullable) id<MTLTexture> fontTexture;
|
||||||
@property (nonatomic, strong) NSMutableArray<MetalBuffer *> *bufferCache;
|
@property (nonatomic, strong) NSMutableArray<MetalBuffer *> *bufferCache;
|
||||||
@property (nonatomic, assign) NSTimeInterval lastBufferCachePurge;
|
@property (nonatomic, assign) double lastBufferCachePurge;
|
||||||
- (void)makeDeviceObjectsWithDevice:(id<MTLDevice>)device;
|
- (void)makeDeviceObjectsWithDevice:(id<MTLDevice>)device;
|
||||||
- (void)makeFontTextureWithDevice:(id<MTLDevice>)device;
|
- (void)makeFontTextureWithDevice:(id<MTLDevice>)device;
|
||||||
- (MetalBuffer *)dequeueReusableBufferOfLength:(NSUInteger)length device:(id<MTLDevice>)device;
|
- (MetalBuffer *)dequeueReusableBufferOfLength:(NSUInteger)length device:(id<MTLDevice>)device;
|
||||||
@@ -79,7 +79,18 @@
|
|||||||
commandEncoder:(id<MTLRenderCommandEncoder>)commandEncoder;
|
commandEncoder:(id<MTLRenderCommandEncoder>)commandEncoder;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
static MetalContext *g_sharedMetalContext = nil;
|
struct ImGui_ImplMetal_Data
|
||||||
|
{
|
||||||
|
MetalContext* SharedMetalContext;
|
||||||
|
|
||||||
|
ImGui_ImplMetal_Data() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
static ImGui_ImplMetal_Data* ImGui_ImplMetal_CreateBackendData() { return IM_NEW(ImGui_ImplMetal_Data)(); }
|
||||||
|
static ImGui_ImplMetal_Data* ImGui_ImplMetal_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplMetal_Data*)ImGui::GetIO().BackendRendererUserData : NULL; }
|
||||||
|
static void ImGui_ImplMetal_DestroyBackendData() { IM_DELETE(ImGui_ImplMetal_GetBackendData()); }
|
||||||
|
|
||||||
|
static inline CFTimeInterval GetMachAbsoluteTimeInSeconds() { return static_cast<CFTimeInterval>(static_cast<double>(clock_gettime_nsec_np(CLOCK_UPTIME_RAW)) / 1e9); }
|
||||||
|
|
||||||
#ifdef IMGUI_IMPL_METAL_CPP
|
#ifdef IMGUI_IMPL_METAL_CPP
|
||||||
|
|
||||||
@@ -121,16 +132,14 @@ bool ImGui_ImplMetal_CreateDeviceObjects(MTL::Device* device)
|
|||||||
|
|
||||||
bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
||||||
{
|
{
|
||||||
|
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_CreateBackendData();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.BackendRendererUserData = (void*)bd;
|
||||||
io.BackendRendererName = "imgui_impl_metal";
|
io.BackendRendererName = "imgui_impl_metal";
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
|
|
||||||
static dispatch_once_t onceToken;
|
bd->SharedMetalContext = [[MetalContext alloc] init];
|
||||||
dispatch_once(&onceToken, ^{
|
bd->SharedMetalContext.device = device;
|
||||||
g_sharedMetalContext = [[MetalContext alloc] init];
|
|
||||||
});
|
|
||||||
|
|
||||||
ImGui_ImplMetal_CreateDeviceObjects(device);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -138,42 +147,48 @@ bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
|||||||
void ImGui_ImplMetal_Shutdown()
|
void ImGui_ImplMetal_Shutdown()
|
||||||
{
|
{
|
||||||
ImGui_ImplMetal_DestroyDeviceObjects();
|
ImGui_ImplMetal_DestroyDeviceObjects();
|
||||||
|
ImGui_ImplMetal_DestroyBackendData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor *renderPassDescriptor)
|
void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor *renderPassDescriptor)
|
||||||
{
|
{
|
||||||
IM_ASSERT(g_sharedMetalContext != nil && "No Metal context. Did you call ImGui_ImplMetal_Init() ?");
|
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||||
|
IM_ASSERT(bd->SharedMetalContext != nil && "No Metal context. Did you call ImGui_ImplMetal_Init() ?");
|
||||||
|
bd->SharedMetalContext.framebufferDescriptor = [[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor];
|
||||||
|
|
||||||
g_sharedMetalContext.framebufferDescriptor = [[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor];
|
if (bd->SharedMetalContext.depthStencilState == nil)
|
||||||
|
ImGui_ImplMetal_CreateDeviceObjects(bd->SharedMetalContext.device);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metal Render function.
|
// Metal Render function.
|
||||||
void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id<MTLCommandBuffer> commandBuffer, id<MTLRenderCommandEncoder> commandEncoder)
|
void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id<MTLCommandBuffer> commandBuffer, id<MTLRenderCommandEncoder> commandEncoder)
|
||||||
{
|
{
|
||||||
[g_sharedMetalContext renderDrawData:draw_data commandBuffer:commandBuffer commandEncoder:commandEncoder];
|
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||||
|
[bd->SharedMetalContext renderDrawData:draw_data commandBuffer:commandBuffer commandEncoder:commandEncoder];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplMetal_CreateFontsTexture(id<MTLDevice> device)
|
bool ImGui_ImplMetal_CreateFontsTexture(id<MTLDevice> device)
|
||||||
{
|
{
|
||||||
[g_sharedMetalContext makeFontTextureWithDevice:device];
|
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.Fonts->SetTexID((__bridge void *)g_sharedMetalContext.fontTexture); // ImTextureID == void*
|
[bd->SharedMetalContext makeFontTextureWithDevice:device];
|
||||||
|
io.Fonts->SetTexID((__bridge void *)bd->SharedMetalContext.fontTexture); // ImTextureID == void*
|
||||||
|
|
||||||
return (g_sharedMetalContext.fontTexture != nil);
|
return (bd->SharedMetalContext.fontTexture != nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplMetal_DestroyFontsTexture()
|
void ImGui_ImplMetal_DestroyFontsTexture()
|
||||||
{
|
{
|
||||||
|
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
g_sharedMetalContext.fontTexture = nil;
|
bd->SharedMetalContext.fontTexture = nil;
|
||||||
io.Fonts->SetTexID(nullptr);
|
io.Fonts->SetTexID(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device)
|
bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device)
|
||||||
{
|
{
|
||||||
[g_sharedMetalContext makeDeviceObjectsWithDevice:device];
|
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||||
|
[bd->SharedMetalContext makeDeviceObjectsWithDevice:device];
|
||||||
ImGui_ImplMetal_CreateFontsTexture(device);
|
ImGui_ImplMetal_CreateFontsTexture(device);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -181,8 +196,9 @@ bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device)
|
|||||||
|
|
||||||
void ImGui_ImplMetal_DestroyDeviceObjects()
|
void ImGui_ImplMetal_DestroyDeviceObjects()
|
||||||
{
|
{
|
||||||
|
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||||
ImGui_ImplMetal_DestroyFontsTexture();
|
ImGui_ImplMetal_DestroyFontsTexture();
|
||||||
[g_sharedMetalContext emptyRenderPipelineStateCache];
|
[bd->SharedMetalContext emptyRenderPipelineStateCache];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - MetalBuffer implementation
|
#pragma mark - MetalBuffer implementation
|
||||||
@@ -193,7 +209,7 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
|
|||||||
if ((self = [super init]))
|
if ((self = [super init]))
|
||||||
{
|
{
|
||||||
_buffer = buffer;
|
_buffer = buffer;
|
||||||
_lastReuseTime = [NSDate date].timeIntervalSince1970;
|
_lastReuseTime = GetMachAbsoluteTimeInSeconds();
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@@ -255,7 +271,7 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
|
|||||||
{
|
{
|
||||||
_renderPipelineStateCache = [NSMutableDictionary dictionary];
|
_renderPipelineStateCache = [NSMutableDictionary dictionary];
|
||||||
_bufferCache = [NSMutableArray array];
|
_bufferCache = [NSMutableArray array];
|
||||||
_lastBufferCachePurge = [NSDate date].timeIntervalSince1970;
|
_lastBufferCachePurge = GetMachAbsoluteTimeInSeconds();
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@@ -295,7 +311,7 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
|
|||||||
|
|
||||||
- (MetalBuffer *)dequeueReusableBufferOfLength:(NSUInteger)length device:(id<MTLDevice>)device
|
- (MetalBuffer *)dequeueReusableBufferOfLength:(NSUInteger)length device:(id<MTLDevice>)device
|
||||||
{
|
{
|
||||||
NSTimeInterval now = [NSDate date].timeIntervalSince1970;
|
uint64_t now = GetMachAbsoluteTimeInSeconds();
|
||||||
|
|
||||||
// Purge old buffers that haven't been useful for a while
|
// Purge old buffers that haven't been useful for a while
|
||||||
if (now - self.lastBufferCachePurge > 1.0)
|
if (now - self.lastBufferCachePurge > 1.0)
|
||||||
@@ -460,8 +476,9 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
|
|||||||
vertexBuffer:(MetalBuffer *)vertexBuffer
|
vertexBuffer:(MetalBuffer *)vertexBuffer
|
||||||
vertexBufferOffset:(size_t)vertexBufferOffset
|
vertexBufferOffset:(size_t)vertexBufferOffset
|
||||||
{
|
{
|
||||||
|
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||||
[commandEncoder setCullMode:MTLCullModeNone];
|
[commandEncoder setCullMode:MTLCullModeNone];
|
||||||
[commandEncoder setDepthStencilState:g_sharedMetalContext.depthStencilState];
|
[commandEncoder setDepthStencilState:bd->SharedMetalContext.depthStencilState];
|
||||||
|
|
||||||
// Setup viewport, orthographic projection matrix
|
// Setup viewport, orthographic projection matrix
|
||||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to
|
// Our visible imgui space lies from draw_data->DisplayPos (top left) to
|
||||||
|
@@ -24,4 +24,3 @@
|
|||||||
IMGUI_IMPL_API bool ImGui_ImplOSX_Init(NSView* _Nonnull view);
|
IMGUI_IMPL_API bool ImGui_ImplOSX_Init(NSView* _Nonnull view);
|
||||||
IMGUI_IMPL_API void ImGui_ImplOSX_Shutdown();
|
IMGUI_IMPL_API void ImGui_ImplOSX_Shutdown();
|
||||||
IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(NSView* _Nullable view);
|
IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(NSView* _Nullable view);
|
||||||
IMGUI_IMPL_API bool ImGui_ImplOSX_HandleEvent(NSEvent* _Nonnull event, NSView* _Nullable view);
|
|
||||||
|
@@ -19,12 +19,14 @@
|
|||||||
#import "imgui.h"
|
#import "imgui.h"
|
||||||
#import "imgui_impl_osx.h"
|
#import "imgui_impl_osx.h"
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import <mach/mach_time.h>
|
|
||||||
#import <Carbon/Carbon.h>
|
#import <Carbon/Carbon.h>
|
||||||
#import <GameController/GameController.h>
|
#import <GameController/GameController.h>
|
||||||
|
#import <time.h>
|
||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2022-05-03: Inputs: Removed ImGui_ImplOSX_HandleEvent() from backend API in favor of backend automatically handling event capture.
|
||||||
|
// 2022-04-27: Misc: Store backend data in a per-context struct, allowing to use this backend with multiple contexts.
|
||||||
// 2022-03-22: Inputs: Monitor NSKeyUp events to catch missing keyUp for key when user press Cmd + key
|
// 2022-03-22: Inputs: Monitor NSKeyUp events to catch missing keyUp for key when user press Cmd + key
|
||||||
// 2022-02-07: Inputs: Forward keyDown/keyUp events to OS when unused by dear imgui.
|
// 2022-02-07: Inputs: Forward keyDown/keyUp events to OS when unused by dear imgui.
|
||||||
// 2022-01-31: Fix building with old Xcode versions that are missing gamepad features.
|
// 2022-01-31: Fix building with old Xcode versions that are missing gamepad features.
|
||||||
@@ -55,17 +57,32 @@
|
|||||||
#define APPLE_HAS_CONTROLLER (__IPHONE_OS_VERSION_MIN_REQUIRED >= 140000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 110000 || __TV_OS_VERSION_MIN_REQUIRED >= 140000)
|
#define APPLE_HAS_CONTROLLER (__IPHONE_OS_VERSION_MIN_REQUIRED >= 140000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 110000 || __TV_OS_VERSION_MIN_REQUIRED >= 140000)
|
||||||
#define APPLE_HAS_THUMBSTICKS (__IPHONE_OS_VERSION_MIN_REQUIRED >= 120100 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101401 || __TV_OS_VERSION_MIN_REQUIRED >= 120100)
|
#define APPLE_HAS_THUMBSTICKS (__IPHONE_OS_VERSION_MIN_REQUIRED >= 120100 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101401 || __TV_OS_VERSION_MIN_REQUIRED >= 120100)
|
||||||
|
|
||||||
@class ImFocusObserver;
|
@class ImGuiObserver;
|
||||||
@class KeyEventResponder;
|
@class KeyEventResponder;
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
static double g_HostClockPeriod = 0.0;
|
struct ImGui_ImplOSX_Data
|
||||||
static double g_Time = 0.0;
|
{
|
||||||
static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {};
|
CFTimeInterval Time;
|
||||||
static bool g_MouseCursorHidden = false;
|
NSCursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
||||||
static ImFocusObserver* g_FocusObserver = nil;
|
bool MouseCursorHidden;
|
||||||
static KeyEventResponder* g_KeyEventResponder = nil;
|
ImGuiObserver* Observer;
|
||||||
static NSTextInputContext* g_InputContext = nil;
|
KeyEventResponder* KeyEventResponder;
|
||||||
|
NSTextInputContext* InputContext;
|
||||||
|
id Monitor;
|
||||||
|
|
||||||
|
ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
static ImGui_ImplOSX_Data* ImGui_ImplOSX_CreateBackendData() { return IM_NEW(ImGui_ImplOSX_Data)(); }
|
||||||
|
static ImGui_ImplOSX_Data* ImGui_ImplOSX_GetBackendData() { return (ImGui_ImplOSX_Data*)ImGui::GetIO().BackendPlatformUserData; }
|
||||||
|
static void ImGui_ImplOSX_DestroyBackendData() { IM_DELETE(ImGui_ImplOSX_GetBackendData()); }
|
||||||
|
|
||||||
|
static inline CFTimeInterval GetMachAbsoluteTimeInSeconds() { return static_cast<CFTimeInterval>(static_cast<double>(clock_gettime_nsec_np(CLOCK_UPTIME_RAW)) / 1e9); }
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
static void ImGui_ImplOSX_AddTrackingArea(NSView* _Nonnull view);
|
||||||
|
static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
||||||
|
|
||||||
// Undocumented methods for creating cursors.
|
// Undocumented methods for creating cursors.
|
||||||
@interface NSCursor()
|
@interface NSCursor()
|
||||||
@@ -75,18 +92,6 @@ static NSTextInputContext* g_InputContext = nil;
|
|||||||
+ (id)_windowResizeEastWestCursor;
|
+ (id)_windowResizeEastWestCursor;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
static void InitHostClockPeriod()
|
|
||||||
{
|
|
||||||
struct mach_timebase_info info;
|
|
||||||
mach_timebase_info(&info);
|
|
||||||
g_HostClockPeriod = 1e-9 * ((double)info.denom / (double)info.numer); // Period is the reciprocal of frequency.
|
|
||||||
}
|
|
||||||
|
|
||||||
static double GetMachAbsoluteTimeInSeconds()
|
|
||||||
{
|
|
||||||
return (double)mach_absolute_time() * g_HostClockPeriod;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
KeyEventResponder implements the NSTextInputClient protocol as is required by the macOS text input manager.
|
KeyEventResponder implements the NSTextInputClient protocol as is required by the macOS text input manager.
|
||||||
|
|
||||||
@@ -215,14 +220,14 @@ static double GetMachAbsoluteTimeInSeconds()
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface ImFocusObserver : NSObject
|
@interface ImGuiObserver : NSObject
|
||||||
|
|
||||||
- (void)onApplicationBecomeActive:(NSNotification*)aNotification;
|
- (void)onApplicationBecomeActive:(NSNotification*)aNotification;
|
||||||
- (void)onApplicationBecomeInactive:(NSNotification*)aNotification;
|
- (void)onApplicationBecomeInactive:(NSNotification*)aNotification;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation ImFocusObserver
|
@implementation ImGuiObserver
|
||||||
|
|
||||||
- (void)onApplicationBecomeActive:(NSNotification*)aNotification
|
- (void)onApplicationBecomeActive:(NSNotification*)aNotification
|
||||||
{
|
{
|
||||||
@@ -365,6 +370,8 @@ static ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code)
|
|||||||
bool ImGui_ImplOSX_Init(NSView* view)
|
bool ImGui_ImplOSX_Init(NSView* view)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_CreateBackendData();
|
||||||
|
io.BackendPlatformUserData = (void*)bd;
|
||||||
|
|
||||||
// Setup backend capabilities flags
|
// Setup backend capabilities flags
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||||
@@ -373,17 +380,19 @@ bool ImGui_ImplOSX_Init(NSView* view)
|
|||||||
//io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
//io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
||||||
io.BackendPlatformName = "imgui_impl_osx";
|
io.BackendPlatformName = "imgui_impl_osx";
|
||||||
|
|
||||||
|
bd->Observer = [ImGuiObserver new];
|
||||||
|
|
||||||
// Load cursors. Some of them are undocumented.
|
// Load cursors. Some of them are undocumented.
|
||||||
g_MouseCursorHidden = false;
|
bd->MouseCursorHidden = false;
|
||||||
g_MouseCursors[ImGuiMouseCursor_Arrow] = [NSCursor arrowCursor];
|
bd->MouseCursors[ImGuiMouseCursor_Arrow] = [NSCursor arrowCursor];
|
||||||
g_MouseCursors[ImGuiMouseCursor_TextInput] = [NSCursor IBeamCursor];
|
bd->MouseCursors[ImGuiMouseCursor_TextInput] = [NSCursor IBeamCursor];
|
||||||
g_MouseCursors[ImGuiMouseCursor_ResizeAll] = [NSCursor closedHandCursor];
|
bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = [NSCursor closedHandCursor];
|
||||||
g_MouseCursors[ImGuiMouseCursor_Hand] = [NSCursor pointingHandCursor];
|
bd->MouseCursors[ImGuiMouseCursor_Hand] = [NSCursor pointingHandCursor];
|
||||||
g_MouseCursors[ImGuiMouseCursor_NotAllowed] = [NSCursor operationNotAllowedCursor];
|
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = [NSCursor operationNotAllowedCursor];
|
||||||
g_MouseCursors[ImGuiMouseCursor_ResizeNS] = [NSCursor respondsToSelector:@selector(_windowResizeNorthSouthCursor)] ? [NSCursor _windowResizeNorthSouthCursor] : [NSCursor resizeUpDownCursor];
|
bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = [NSCursor respondsToSelector:@selector(_windowResizeNorthSouthCursor)] ? [NSCursor _windowResizeNorthSouthCursor] : [NSCursor resizeUpDownCursor];
|
||||||
g_MouseCursors[ImGuiMouseCursor_ResizeEW] = [NSCursor respondsToSelector:@selector(_windowResizeEastWestCursor)] ? [NSCursor _windowResizeEastWestCursor] : [NSCursor resizeLeftRightCursor];
|
bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = [NSCursor respondsToSelector:@selector(_windowResizeEastWestCursor)] ? [NSCursor _windowResizeEastWestCursor] : [NSCursor resizeLeftRightCursor];
|
||||||
g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = [NSCursor respondsToSelector:@selector(_windowResizeNorthEastSouthWestCursor)] ? [NSCursor _windowResizeNorthEastSouthWestCursor] : [NSCursor closedHandCursor];
|
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = [NSCursor respondsToSelector:@selector(_windowResizeNorthEastSouthWestCursor)] ? [NSCursor _windowResizeNorthEastSouthWestCursor] : [NSCursor closedHandCursor];
|
||||||
g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = [NSCursor respondsToSelector:@selector(_windowResizeNorthWestSouthEastCursor)] ? [NSCursor _windowResizeNorthWestSouthEastCursor] : [NSCursor closedHandCursor];
|
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = [NSCursor respondsToSelector:@selector(_windowResizeNorthWestSouthEastCursor)] ? [NSCursor _windowResizeNorthWestSouthEastCursor] : [NSCursor closedHandCursor];
|
||||||
|
|
||||||
// Note that imgui.cpp also include default OSX clipboard handlers which can be enabled
|
// Note that imgui.cpp also include default OSX clipboard handlers which can be enabled
|
||||||
// by adding '#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS' in imconfig.h and adding '-framework ApplicationServices' to your linker command-line.
|
// by adding '#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS' in imconfig.h and adding '-framework ApplicationServices' to your linker command-line.
|
||||||
@@ -414,44 +423,36 @@ bool ImGui_ImplOSX_Init(NSView* view)
|
|||||||
return s_clipboard.Data;
|
return s_clipboard.Data;
|
||||||
};
|
};
|
||||||
|
|
||||||
g_FocusObserver = [[ImFocusObserver alloc] init];
|
[[NSNotificationCenter defaultCenter] addObserver:bd->Observer
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:g_FocusObserver
|
|
||||||
selector:@selector(onApplicationBecomeActive:)
|
selector:@selector(onApplicationBecomeActive:)
|
||||||
name:NSApplicationDidBecomeActiveNotification
|
name:NSApplicationDidBecomeActiveNotification
|
||||||
object:nil];
|
object:nil];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:g_FocusObserver
|
[[NSNotificationCenter defaultCenter] addObserver:bd->Observer
|
||||||
selector:@selector(onApplicationBecomeInactive:)
|
selector:@selector(onApplicationBecomeInactive:)
|
||||||
name:NSApplicationDidResignActiveNotification
|
name:NSApplicationDidResignActiveNotification
|
||||||
object:nil];
|
object:nil];
|
||||||
|
|
||||||
// Add the NSTextInputClient to the view hierarchy,
|
// Add the NSTextInputClient to the view hierarchy,
|
||||||
// to receive keyboard events and translate them to input text.
|
// to receive keyboard events and translate them to input text.
|
||||||
g_KeyEventResponder = [[KeyEventResponder alloc] initWithFrame:NSZeroRect];
|
bd->KeyEventResponder = [[KeyEventResponder alloc] initWithFrame:NSZeroRect];
|
||||||
g_InputContext = [[NSTextInputContext alloc] initWithClient:g_KeyEventResponder];
|
bd->InputContext = [[NSTextInputContext alloc] initWithClient:bd->KeyEventResponder];
|
||||||
[view addSubview:g_KeyEventResponder];
|
[view addSubview:bd->KeyEventResponder];
|
||||||
|
ImGui_ImplOSX_AddTrackingArea(view);
|
||||||
// Some events do not raise callbacks of AppView in some circumstances (for example when CMD key is held down).
|
|
||||||
// This monitor taps into global event stream and captures these events.
|
|
||||||
NSEventMask eventMask = NSEventMaskFromType(NSKeyUp) | NSEventMaskFlagsChanged;
|
|
||||||
[NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event)
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_HandleEvent(event, g_KeyEventResponder);
|
|
||||||
return event;
|
|
||||||
}];
|
|
||||||
|
|
||||||
io.SetPlatformImeDataFn = [](ImGuiViewport* viewport, ImGuiPlatformImeData* data) -> void
|
io.SetPlatformImeDataFn = [](ImGuiViewport* viewport, ImGuiPlatformImeData* data) -> void
|
||||||
{
|
{
|
||||||
|
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||||
if (data->WantVisible)
|
if (data->WantVisible)
|
||||||
{
|
{
|
||||||
[g_InputContext activate];
|
[bd->InputContext activate];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[g_InputContext discardMarkedText];
|
[bd->InputContext discardMarkedText];
|
||||||
[g_InputContext invalidateCharacterCoordinates];
|
[bd->InputContext invalidateCharacterCoordinates];
|
||||||
[g_InputContext deactivate];
|
[bd->InputContext deactivate];
|
||||||
}
|
}
|
||||||
[g_KeyEventResponder setImePosX:data->InputPos.x imePosY:data->InputPos.y + data->InputLineHeight];
|
[bd->KeyEventResponder setImePosX:data->InputPos.x imePosY:data->InputPos.y + data->InputLineHeight];
|
||||||
};
|
};
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -459,11 +460,19 @@ bool ImGui_ImplOSX_Init(NSView* view)
|
|||||||
|
|
||||||
void ImGui_ImplOSX_Shutdown()
|
void ImGui_ImplOSX_Shutdown()
|
||||||
{
|
{
|
||||||
g_FocusObserver = NULL;
|
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||||
|
bd->Observer = NULL;
|
||||||
|
if (bd->Monitor != NULL)
|
||||||
|
{
|
||||||
|
[NSEvent removeMonitor:bd->Monitor];
|
||||||
|
bd->Monitor = NULL;
|
||||||
|
}
|
||||||
|
ImGui_ImplOSX_DestroyBackendData();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplOSX_UpdateMouseCursor()
|
static void ImGui_ImplOSX_UpdateMouseCursor()
|
||||||
{
|
{
|
||||||
|
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
|
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
|
||||||
return;
|
return;
|
||||||
@@ -472,23 +481,23 @@ static void ImGui_ImplOSX_UpdateMouseCursor()
|
|||||||
if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
|
if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
|
||||||
{
|
{
|
||||||
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
||||||
if (!g_MouseCursorHidden)
|
if (!bd->MouseCursorHidden)
|
||||||
{
|
{
|
||||||
g_MouseCursorHidden = true;
|
bd->MouseCursorHidden = true;
|
||||||
[NSCursor hide];
|
[NSCursor hide];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NSCursor* desired = g_MouseCursors[imgui_cursor] ?: g_MouseCursors[ImGuiMouseCursor_Arrow];
|
NSCursor* desired = bd->MouseCursors[imgui_cursor] ?: bd->MouseCursors[ImGuiMouseCursor_Arrow];
|
||||||
// -[NSCursor set] generates measureable overhead if called unconditionally.
|
// -[NSCursor set] generates measureable overhead if called unconditionally.
|
||||||
if (desired != NSCursor.currentCursor)
|
if (desired != NSCursor.currentCursor)
|
||||||
{
|
{
|
||||||
[desired set];
|
[desired set];
|
||||||
}
|
}
|
||||||
if (g_MouseCursorHidden)
|
if (bd->MouseCursorHidden)
|
||||||
{
|
{
|
||||||
g_MouseCursorHidden = false;
|
bd->MouseCursorHidden = false;
|
||||||
[NSCursor unhide];
|
[NSCursor unhide];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -555,15 +564,18 @@ static void ImGui_ImplOSX_UpdateGamepads()
|
|||||||
|
|
||||||
static void ImGui_ImplOSX_UpdateImePosWithView(NSView* view)
|
static void ImGui_ImplOSX_UpdateImePosWithView(NSView* view)
|
||||||
{
|
{
|
||||||
|
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
if (io.WantTextInput)
|
if (io.WantTextInput)
|
||||||
[g_KeyEventResponder updateImePosWithView:view];
|
[bd->KeyEventResponder updateImePosWithView:view];
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplOSX_NewFrame(NSView* view)
|
void ImGui_ImplOSX_NewFrame(NSView* view)
|
||||||
{
|
{
|
||||||
// Setup display size
|
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
// Setup display size
|
||||||
if (view)
|
if (view)
|
||||||
{
|
{
|
||||||
const float dpi = (float)[view.window backingScaleFactor];
|
const float dpi = (float)[view.window backingScaleFactor];
|
||||||
@@ -572,21 +584,19 @@ void ImGui_ImplOSX_NewFrame(NSView* view)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup time step
|
// Setup time step
|
||||||
if (g_Time == 0.0)
|
if (bd->Time == 0.0)
|
||||||
{
|
bd->Time = GetMachAbsoluteTimeInSeconds();
|
||||||
InitHostClockPeriod();
|
|
||||||
g_Time = GetMachAbsoluteTimeInSeconds();
|
|
||||||
}
|
|
||||||
double current_time = GetMachAbsoluteTimeInSeconds();
|
double current_time = GetMachAbsoluteTimeInSeconds();
|
||||||
io.DeltaTime = (float)(current_time - g_Time);
|
io.DeltaTime = (float)(current_time - bd->Time);
|
||||||
g_Time = current_time;
|
bd->Time = current_time;
|
||||||
|
|
||||||
ImGui_ImplOSX_UpdateMouseCursor();
|
ImGui_ImplOSX_UpdateMouseCursor();
|
||||||
ImGui_ImplOSX_UpdateGamepads();
|
ImGui_ImplOSX_UpdateGamepads();
|
||||||
ImGui_ImplOSX_UpdateImePosWithView(view);
|
ImGui_ImplOSX_UpdateImePosWithView(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
|
static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
@@ -711,3 +721,27 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplOSX_AddTrackingArea(NSView* _Nonnull view)
|
||||||
|
{
|
||||||
|
// If we want to receive key events, we either need to be in the responder chain of the key view,
|
||||||
|
// or else we can install a local monitor. The consequence of this heavy-handed approach is that
|
||||||
|
// we receive events for all controls, not just Dear ImGui widgets. If we had native controls in our
|
||||||
|
// window, we'd want to be much more careful than just ingesting the complete event stream.
|
||||||
|
// To match the behavior of other backends, we pass every event down to the OS.
|
||||||
|
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||||
|
if (bd->Monitor)
|
||||||
|
return;
|
||||||
|
NSEventMask eventMask = 0;
|
||||||
|
eventMask |= NSEventMaskMouseMoved | NSEventMaskScrollWheel;
|
||||||
|
eventMask |= NSEventMaskLeftMouseDown | NSEventMaskLeftMouseUp | NSEventMaskLeftMouseDragged;
|
||||||
|
eventMask |= NSEventMaskRightMouseDown | NSEventMaskRightMouseUp | NSEventMaskRightMouseDragged;
|
||||||
|
eventMask |= NSEventMaskOtherMouseDown | NSEventMaskOtherMouseUp | NSEventMaskOtherMouseDragged;
|
||||||
|
eventMask |= NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged;
|
||||||
|
bd->Monitor = [NSEvent addLocalMonitorForEventsMatchingMask:eventMask
|
||||||
|
handler:^NSEvent* _Nullable(NSEvent* event)
|
||||||
|
{
|
||||||
|
ImGui_ImplOSX_HandleEvent(event, view);
|
||||||
|
return event;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
@@ -149,7 +149,7 @@ struct ImGui_ImplVulkanH_Window
|
|||||||
ImGui_ImplVulkanH_Window()
|
ImGui_ImplVulkanH_Window()
|
||||||
{
|
{
|
||||||
memset((void*)this, 0, sizeof(*this));
|
memset((void*)this, 0, sizeof(*this));
|
||||||
PresentMode = VK_PRESENT_MODE_MAX_ENUM_KHR;
|
PresentMode = (VkPresentModeKHR)~0; // Ensure we get an error if user doesn't set this.
|
||||||
ClearEnable = true;
|
ClearEnable = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -106,6 +106,10 @@ Breaking changes:
|
|||||||
|
|
||||||
- Renamed ImGuiKeyModFlags to ImGuiModFlags. Kept inline redirection enums (will obsolete).
|
- Renamed ImGuiKeyModFlags to ImGuiModFlags. Kept inline redirection enums (will obsolete).
|
||||||
(This was never used in public API functions but technically present in imgui.h and ImGuiIO).
|
(This was never used in public API functions but technically present in imgui.h and ImGuiIO).
|
||||||
|
- Backends: OSX: Removed ImGui_ImplOSX_HandleEvent() from backend API in favor of backend
|
||||||
|
automatically handling event capture. Examples that are using the OSX backend have removed
|
||||||
|
all the now-unnecessary calls to ImGui_ImplOSX_HandleEvent(), applications can do as well.
|
||||||
|
[@stuartcarnie] (#4821)
|
||||||
|
|
||||||
Other Changes:
|
Other Changes:
|
||||||
|
|
||||||
@@ -141,6 +145,7 @@ Other Changes:
|
|||||||
trickled with the new input queue (happened on some backends only). (#2467, #1336)
|
trickled with the new input queue (happened on some backends only). (#2467, #1336)
|
||||||
- Tables: Fixed incorrect border height used for logic when resizing one of several synchronized
|
- Tables: Fixed incorrect border height used for logic when resizing one of several synchronized
|
||||||
instance of a same table ID, when instances have a different height. (#3955).
|
instance of a same table ID, when instances have a different height. (#3955).
|
||||||
|
- Tables: Fixed incorrect auto-fit of parent windows when using non-resizable weighted columns. (#5276)
|
||||||
- Inputs: Fixed IsMouseClicked() repeat mode rate being half of keyboard repeat rate.
|
- Inputs: Fixed IsMouseClicked() repeat mode rate being half of keyboard repeat rate.
|
||||||
- ColorEdit: Fixed text baseline alignment after a SameLine() after a ColorEdit() with visible label.
|
- ColorEdit: Fixed text baseline alignment after a SameLine() after a ColorEdit() with visible label.
|
||||||
- Menus: Adjusted BeginMenu() closing logic so hovering void or non-MenuItem() in parent window
|
- Menus: Adjusted BeginMenu() closing logic so hovering void or non-MenuItem() in parent window
|
||||||
@@ -160,13 +165,18 @@ Other Changes:
|
|||||||
- Misc: Updated stb_rect_pack.h from 1.00 to 1.01 (minor). (#5075)
|
- Misc: Updated stb_rect_pack.h from 1.00 to 1.01 (minor). (#5075)
|
||||||
- Misc: binary_to_compressed_c tool: Added -nostatic option. (#5021) [@podsvirov]
|
- Misc: binary_to_compressed_c tool: Added -nostatic option. (#5021) [@podsvirov]
|
||||||
- ImVector: Fixed erase() with empty range. (#5009) [@thedmd]
|
- ImVector: Fixed erase() with empty range. (#5009) [@thedmd]
|
||||||
|
- Backends: Vulkan: Don't use VK_PRESENT_MODE_MAX_ENUM_KHR as specs state it isn't part of the API. (#5254)
|
||||||
- Backends: GLFW: Fixed a regression in 1.87 which resulted in keyboard modifiers events being
|
- Backends: GLFW: Fixed a regression in 1.87 which resulted in keyboard modifiers events being
|
||||||
reported incorrectly on Linux/X11, due to a bug in GLFW. [@rokups]
|
reported incorrectly on Linux/X11, due to a bug in GLFW. [@rokups]
|
||||||
|
- Backends: GLFW: Fixed untranslated keys when pressing lower case letters on OSX (#5260, #5261) [@cpichard]
|
||||||
- Backends: SDL: Fixed dragging out viewport broken on some SDL setups. (#5012) [@rokups]
|
- Backends: SDL: Fixed dragging out viewport broken on some SDL setups. (#5012) [@rokups]
|
||||||
- Backends: SDL: Added support for extra mouse buttons (SDL_BUTTON_X1/SDL_BUTTON_X2). (#5125) [@sgiurgiu]
|
- Backends: SDL: Added support for extra mouse buttons (SDL_BUTTON_X1/SDL_BUTTON_X2). (#5125) [@sgiurgiu]
|
||||||
- Backends: SDL, OpenGL3: Fixes to facilitate building on AmigaOS4. (#5190) [@afxgroup]
|
- Backends: SDL, OpenGL3: Fixes to facilitate building on AmigaOS4. (#5190) [@afxgroup]
|
||||||
- Backends: OSX: Monitor NSKeyUp events to catch missing keyUp for key when user press Cmd + key (#5128) [@thedmd]
|
- Backends: OSX: Monitor NSKeyUp events to catch missing keyUp for key when user press Cmd + key (#5128) [@thedmd]
|
||||||
- Examples: Emscripten: Fix building for latest Emscripten specs. (#3632)
|
- Backends: OSX, Metal: Store backend data in a per-context struct, allowing to use these backends with
|
||||||
|
multiple contexts. (#5203, #5221, #4141) [@noisewuwei]
|
||||||
|
- Examples: Emscripten+WebGPU: Fix building for latest WebGPU specs. (#3632)
|
||||||
|
- Examples: OSX+Metal, OSX+OpenGL: Removed now-unnecessary calls to ImGui_ImplOSX_HandleEvent(). (#4821)
|
||||||
|
|
||||||
Docking+Viewports Branch:
|
Docking+Viewports Branch:
|
||||||
|
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
#include "imgui_impl_metal.h"
|
#include "imgui_impl_metal.h"
|
||||||
#if TARGET_OS_OSX
|
#if TARGET_OS_OSX
|
||||||
#include "imgui_impl_osx.h"
|
#include "imgui_impl_osx.h"
|
||||||
@interface AppViewController : NSViewController
|
@interface AppViewController : NSViewController<NSWindowDelegate>
|
||||||
@end
|
@end
|
||||||
#else
|
#else
|
||||||
@interface AppViewController : UIViewController
|
@interface AppViewController : UIViewController
|
||||||
@@ -100,15 +100,8 @@
|
|||||||
self.mtkView.delegate = self;
|
self.mtkView.delegate = self;
|
||||||
|
|
||||||
#if TARGET_OS_OSX
|
#if TARGET_OS_OSX
|
||||||
// Add a tracking area in order to receive mouse events whenever the mouse is within the bounds of our view
|
|
||||||
NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect
|
|
||||||
options:NSTrackingMouseMoved | NSTrackingInVisibleRect | NSTrackingActiveAlways
|
|
||||||
owner:self
|
|
||||||
userInfo:nil];
|
|
||||||
[self.view addTrackingArea:trackingArea];
|
|
||||||
|
|
||||||
ImGui_ImplOSX_Init(self.view);
|
ImGui_ImplOSX_Init(self.view);
|
||||||
|
[NSApp activateIgnoringOtherApps:YES];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,8 +118,6 @@
|
|||||||
#endif
|
#endif
|
||||||
io.DisplayFramebufferScale = ImVec2(framebufferScale, framebufferScale);
|
io.DisplayFramebufferScale = ImVec2(framebufferScale, framebufferScale);
|
||||||
|
|
||||||
io.DeltaTime = 1 / float(view.preferredFramesPerSecond ?: 60);
|
|
||||||
|
|
||||||
id<MTLCommandBuffer> commandBuffer = [self.commandQueue commandBuffer];
|
id<MTLCommandBuffer> commandBuffer = [self.commandQueue commandBuffer];
|
||||||
|
|
||||||
MTLRenderPassDescriptor* renderPassDescriptor = view.currentRenderPassDescriptor;
|
MTLRenderPassDescriptor* renderPassDescriptor = view.currentRenderPassDescriptor;
|
||||||
@@ -211,20 +202,18 @@
|
|||||||
|
|
||||||
#if TARGET_OS_OSX
|
#if TARGET_OS_OSX
|
||||||
|
|
||||||
// Forward Mouse events to Dear ImGui OSX backend.
|
- (void)viewWillAppear
|
||||||
-(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
{
|
||||||
-(void)rightMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
[super viewWillAppear];
|
||||||
-(void)otherMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
self.view.window.delegate = self;
|
||||||
-(void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
}
|
||||||
-(void)rightMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
|
||||||
-(void)otherMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
- (void)windowWillClose:(NSNotification *)notification
|
||||||
-(void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
{
|
||||||
-(void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
ImGui_ImplMetal_Shutdown();
|
||||||
-(void)rightMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
ImGui_ImplOSX_Shutdown();
|
||||||
-(void)rightMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
ImGui::DestroyContext();
|
||||||
-(void)otherMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
}
|
||||||
-(void)otherMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
|
||||||
-(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -288,9 +277,8 @@
|
|||||||
backing:NSBackingStoreBuffered
|
backing:NSBackingStoreBuffered
|
||||||
defer:NO];
|
defer:NO];
|
||||||
self.window.contentViewController = rootViewController;
|
self.window.contentViewController = rootViewController;
|
||||||
[self.window orderFront:self];
|
|
||||||
[self.window center];
|
[self.window center];
|
||||||
[self.window becomeKeyWindow];
|
[self.window makeKeyAndOrderFront:self];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@@ -143,26 +143,6 @@
|
|||||||
-(void)animationTimerFired:(NSTimer*)timer { [self setNeedsDisplay:YES]; }
|
-(void)animationTimerFired:(NSTimer*)timer { [self setNeedsDisplay:YES]; }
|
||||||
-(void)dealloc { animationTimer = nil; }
|
-(void)dealloc { animationTimer = nil; }
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------
|
|
||||||
// Input processing
|
|
||||||
//-----------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Forward Mouse/Keyboard events to Dear ImGui OSX backend.
|
|
||||||
// Other events are registered via addLocalMonitorForEventsMatchingMask()
|
|
||||||
-(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
|
|
||||||
-(void)rightMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
|
|
||||||
-(void)otherMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
|
|
||||||
-(void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
|
|
||||||
-(void)rightMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
|
|
||||||
-(void)otherMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
|
|
||||||
-(void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
|
|
||||||
-(void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
|
|
||||||
-(void)rightMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
|
|
||||||
-(void)rightMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
|
|
||||||
-(void)otherMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
|
|
||||||
-(void)otherMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
|
|
||||||
-(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
|
@@ -205,7 +205,7 @@ static void main_loop(void* window)
|
|||||||
WGPURenderPassColorAttachment color_attachments = {};
|
WGPURenderPassColorAttachment color_attachments = {};
|
||||||
color_attachments.loadOp = WGPULoadOp_Clear;
|
color_attachments.loadOp = WGPULoadOp_Clear;
|
||||||
color_attachments.storeOp = WGPUStoreOp_Store;
|
color_attachments.storeOp = WGPUStoreOp_Store;
|
||||||
color_attachments.clearColor = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };
|
color_attachments.clearValue = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };
|
||||||
color_attachments.view = wgpuSwapChainGetCurrentTextureView(wgpu_swap_chain);
|
color_attachments.view = wgpuSwapChainGetCurrentTextureView(wgpu_swap_chain);
|
||||||
WGPURenderPassDescriptor render_pass_desc = {};
|
WGPURenderPassDescriptor render_pass_desc = {};
|
||||||
render_pass_desc.colorAttachmentCount = 1;
|
render_pass_desc.colorAttachmentCount = 1;
|
||||||
|
47
imgui.cpp
47
imgui.cpp
@@ -388,12 +388,13 @@ 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)
|
||||||
- 2021/XX/XX (1.XX) - when multi-viewports are enabled, all positions will be in your natural OS coordinates space. It means that:
|
- 2022/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.
|
||||||
|
|
||||||
|
- 2022/05/03 (1.88) - backends: osx: removed ImGui_ImplOSX_HandleEvent() from backend API in favor of backend automatically handling event capture. All ImGui_ImplOSX_HandleEvent() calls should be removed as they are now unnecessary.
|
||||||
- 2022/04/05 (1.88) - inputs: renamed ImGuiKeyModFlags to ImGuiModFlags. Kept inline redirection enums (will obsolete). This was never used in public API functions but technically present in imgui.h and ImGuiIO.
|
- 2022/04/05 (1.88) - inputs: renamed ImGuiKeyModFlags to ImGuiModFlags. Kept inline redirection enums (will obsolete). This was never used in public API functions but technically present in imgui.h and ImGuiIO.
|
||||||
- 2022/01/20 (1.87) - inputs: reworded gamepad IO.
|
- 2022/01/20 (1.87) - inputs: reworded gamepad IO.
|
||||||
- Backend writing to io.NavInputs[] -> backend should call io.AddKeyEvent()/io.AddKeyAnalogEvent() with ImGuiKey_GamepadXXX values.
|
- Backend writing to io.NavInputs[] -> backend should call io.AddKeyEvent()/io.AddKeyAnalogEvent() with ImGuiKey_GamepadXXX values.
|
||||||
@@ -4129,9 +4130,9 @@ static void ImGui::UpdateKeyboardInputs()
|
|||||||
// Update keys
|
// Update keys
|
||||||
for (int i = 0; i < IM_ARRAYSIZE(io.KeysData); i++)
|
for (int i = 0; i < IM_ARRAYSIZE(io.KeysData); i++)
|
||||||
{
|
{
|
||||||
ImGuiKeyData& key_data = io.KeysData[i];
|
ImGuiKeyData* key_data = &io.KeysData[i];
|
||||||
key_data.DownDurationPrev = key_data.DownDuration;
|
key_data->DownDurationPrev = key_data->DownDuration;
|
||||||
key_data.DownDuration = key_data.Down ? (key_data.DownDuration < 0.0f ? 0.0f : key_data.DownDuration + io.DeltaTime) : -1.0f;
|
key_data->DownDuration = key_data->Down ? (key_data->DownDuration < 0.0f ? 0.0f : key_data->DownDuration + io.DeltaTime) : -1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5953,9 +5954,9 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
|||||||
{
|
{
|
||||||
ImVec2 nav_resize_delta;
|
ImVec2 nav_resize_delta;
|
||||||
if (g.NavInputSource == ImGuiInputSource_Keyboard && g.IO.KeyShift)
|
if (g.NavInputSource == ImGuiInputSource_Keyboard && g.IO.KeyShift)
|
||||||
nav_resize_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_RawKeyboard, ImGuiInputReadMode_Down);
|
nav_resize_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_RawKeyboard, ImGuiNavReadMode_Down);
|
||||||
if (g.NavInputSource == ImGuiInputSource_Gamepad)
|
if (g.NavInputSource == ImGuiInputSource_Gamepad)
|
||||||
nav_resize_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_Down);
|
nav_resize_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadDPad, ImGuiNavReadMode_Down);
|
||||||
if (nav_resize_delta.x != 0.0f || nav_resize_delta.y != 0.0f)
|
if (nav_resize_delta.x != 0.0f || nav_resize_delta.y != 0.0f)
|
||||||
{
|
{
|
||||||
const float NAV_RESIZE_SPEED = 600.0f;
|
const float NAV_RESIZE_SPEED = 600.0f;
|
||||||
@@ -10679,29 +10680,29 @@ const char* ImGui::GetNavInputName(ImGuiNavInput n)
|
|||||||
return names[n];
|
return names[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
float ImGui::GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode)
|
float ImGui::GetNavInputAmount(ImGuiNavInput n, ImGuiNavReadMode mode)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (mode == ImGuiInputReadMode_Down)
|
if (mode == ImGuiNavReadMode_Down)
|
||||||
return g.IO.NavInputs[n]; // Instant, read analog input (0.0f..1.0f, as provided by user)
|
return g.IO.NavInputs[n]; // Instant, read analog input (0.0f..1.0f, as provided by user)
|
||||||
|
|
||||||
const float t = g.IO.NavInputsDownDuration[n];
|
const float t = g.IO.NavInputsDownDuration[n];
|
||||||
if (t < 0.0f && mode == ImGuiInputReadMode_Released) // Return 1.0f when just released, no repeat, ignore analog input.
|
if (t < 0.0f && mode == ImGuiNavReadMode_Released) // Return 1.0f when just released, no repeat, ignore analog input.
|
||||||
return (g.IO.NavInputsDownDurationPrev[n] >= 0.0f ? 1.0f : 0.0f);
|
return (g.IO.NavInputsDownDurationPrev[n] >= 0.0f ? 1.0f : 0.0f);
|
||||||
if (t < 0.0f)
|
if (t < 0.0f)
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
if (mode == ImGuiInputReadMode_Pressed) // Return 1.0f when just pressed, no repeat, ignore analog input.
|
if (mode == ImGuiNavReadMode_Pressed) // Return 1.0f when just pressed, no repeat, ignore analog input.
|
||||||
return (t == 0.0f) ? 1.0f : 0.0f;
|
return (t == 0.0f) ? 1.0f : 0.0f;
|
||||||
if (mode == ImGuiInputReadMode_Repeat)
|
if (mode == ImGuiNavReadMode_Repeat)
|
||||||
return (float)CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay * 0.72f, g.IO.KeyRepeatRate * 0.80f);
|
return (float)CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay * 0.72f, g.IO.KeyRepeatRate * 0.80f);
|
||||||
if (mode == ImGuiInputReadMode_RepeatSlow)
|
if (mode == ImGuiNavReadMode_RepeatSlow)
|
||||||
return (float)CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay * 1.25f, g.IO.KeyRepeatRate * 2.00f);
|
return (float)CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay * 1.25f, g.IO.KeyRepeatRate * 2.00f);
|
||||||
if (mode == ImGuiInputReadMode_RepeatFast)
|
if (mode == ImGuiNavReadMode_RepeatFast)
|
||||||
return (float)CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay * 0.72f, g.IO.KeyRepeatRate * 0.30f);
|
return (float)CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay * 0.72f, g.IO.KeyRepeatRate * 0.30f);
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImVec2 ImGui::GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor, float fast_factor)
|
ImVec2 ImGui::GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiNavReadMode mode, float slow_factor, float fast_factor)
|
||||||
{
|
{
|
||||||
ImVec2 delta(0.0f, 0.0f);
|
ImVec2 delta(0.0f, 0.0f);
|
||||||
if (dir_sources & ImGuiNavDirSourceFlags_RawKeyboard)
|
if (dir_sources & ImGuiNavDirSourceFlags_RawKeyboard)
|
||||||
@@ -10821,8 +10822,8 @@ static void ImGui::NavUpdate()
|
|||||||
{
|
{
|
||||||
bool activate_down = IsNavInputDown(ImGuiNavInput_Activate);
|
bool activate_down = IsNavInputDown(ImGuiNavInput_Activate);
|
||||||
bool input_down = IsNavInputDown(ImGuiNavInput_Input);
|
bool input_down = IsNavInputDown(ImGuiNavInput_Input);
|
||||||
bool activate_pressed = activate_down && IsNavInputTest(ImGuiNavInput_Activate, ImGuiInputReadMode_Pressed);
|
bool activate_pressed = activate_down && IsNavInputTest(ImGuiNavInput_Activate, ImGuiNavReadMode_Pressed);
|
||||||
bool input_pressed = input_down && IsNavInputTest(ImGuiNavInput_Input, ImGuiInputReadMode_Pressed);
|
bool input_pressed = input_down && IsNavInputTest(ImGuiNavInput_Input, ImGuiNavReadMode_Pressed);
|
||||||
if (g.ActiveId == 0 && activate_pressed)
|
if (g.ActiveId == 0 && activate_pressed)
|
||||||
{
|
{
|
||||||
g.NavActivateId = g.NavId;
|
g.NavActivateId = g.NavId;
|
||||||
@@ -10879,7 +10880,7 @@ static void ImGui::NavUpdate()
|
|||||||
|
|
||||||
// *Normal* Manual scroll with NavScrollXXX keys
|
// *Normal* Manual scroll with NavScrollXXX keys
|
||||||
// Next movement request will clamp the NavId reference rectangle to the visible area, so navigation will resume within those bounds.
|
// Next movement request will clamp the NavId reference rectangle to the visible area, so navigation will resume within those bounds.
|
||||||
ImVec2 scroll_dir = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down, 1.0f / 10.0f, 10.0f);
|
ImVec2 scroll_dir = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiNavReadMode_Down, 1.0f / 10.0f, 10.0f);
|
||||||
if (scroll_dir.x != 0.0f && window->ScrollbarX)
|
if (scroll_dir.x != 0.0f && window->ScrollbarX)
|
||||||
SetScrollX(window, ImFloor(window->Scroll.x + scroll_dir.x * scroll_speed));
|
SetScrollX(window, ImFloor(window->Scroll.x + scroll_dir.x * scroll_speed));
|
||||||
if (scroll_dir.y != 0.0f)
|
if (scroll_dir.y != 0.0f)
|
||||||
@@ -10952,7 +10953,7 @@ void ImGui::NavUpdateCreateMoveRequest()
|
|||||||
g.NavMoveScrollFlags = ImGuiScrollFlags_None;
|
g.NavMoveScrollFlags = ImGuiScrollFlags_None;
|
||||||
if (window && !g.NavWindowingTarget && !(window->Flags & ImGuiWindowFlags_NoNavInputs))
|
if (window && !g.NavWindowingTarget && !(window->Flags & ImGuiWindowFlags_NoNavInputs))
|
||||||
{
|
{
|
||||||
const ImGuiInputReadMode read_mode = ImGuiInputReadMode_Repeat;
|
const ImGuiNavReadMode read_mode = ImGuiNavReadMode_Repeat;
|
||||||
if (!IsActiveIdUsingNavDir(ImGuiDir_Left) && (IsNavInputTest(ImGuiNavInput_DpadLeft, read_mode) || IsNavInputTest(ImGuiNavInput_KeyLeft_, read_mode))) { g.NavMoveDir = ImGuiDir_Left; }
|
if (!IsActiveIdUsingNavDir(ImGuiDir_Left) && (IsNavInputTest(ImGuiNavInput_DpadLeft, read_mode) || IsNavInputTest(ImGuiNavInput_KeyLeft_, read_mode))) { g.NavMoveDir = ImGuiDir_Left; }
|
||||||
if (!IsActiveIdUsingNavDir(ImGuiDir_Right) && (IsNavInputTest(ImGuiNavInput_DpadRight, read_mode) || IsNavInputTest(ImGuiNavInput_KeyRight_, read_mode))) { g.NavMoveDir = ImGuiDir_Right; }
|
if (!IsActiveIdUsingNavDir(ImGuiDir_Right) && (IsNavInputTest(ImGuiNavInput_DpadRight, read_mode) || IsNavInputTest(ImGuiNavInput_KeyRight_, read_mode))) { g.NavMoveDir = ImGuiDir_Right; }
|
||||||
if (!IsActiveIdUsingNavDir(ImGuiDir_Up) && (IsNavInputTest(ImGuiNavInput_DpadUp, read_mode) || IsNavInputTest(ImGuiNavInput_KeyUp_, read_mode))) { g.NavMoveDir = ImGuiDir_Up; }
|
if (!IsActiveIdUsingNavDir(ImGuiDir_Up) && (IsNavInputTest(ImGuiNavInput_DpadUp, read_mode) || IsNavInputTest(ImGuiNavInput_KeyUp_, read_mode))) { g.NavMoveDir = ImGuiDir_Up; }
|
||||||
@@ -11159,7 +11160,7 @@ void ImGui::NavMoveRequestApplyResult()
|
|||||||
static void ImGui::NavUpdateCancelRequest()
|
static void ImGui::NavUpdateCancelRequest()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (!IsNavInputTest(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed))
|
if (!IsNavInputTest(ImGuiNavInput_Cancel, ImGuiNavReadMode_Pressed))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IMGUI_DEBUG_LOG_NAV("[nav] ImGuiNavInput_Cancel\n");
|
IMGUI_DEBUG_LOG_NAV("[nav] ImGuiNavInput_Cancel\n");
|
||||||
@@ -11409,7 +11410,7 @@ static void ImGui::NavUpdateWindowing()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start CTRL+Tab or Square+L/R window selection
|
// Start CTRL+Tab or Square+L/R window selection
|
||||||
const bool start_windowing_with_gamepad = allow_windowing && !g.NavWindowingTarget && IsNavInputTest(ImGuiNavInput_Menu, ImGuiInputReadMode_Pressed);
|
const bool start_windowing_with_gamepad = allow_windowing && !g.NavWindowingTarget && IsNavInputTest(ImGuiNavInput_Menu, ImGuiNavReadMode_Pressed);
|
||||||
const bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && io.KeyCtrl && IsKeyPressed(ImGuiKey_Tab);
|
const bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && io.KeyCtrl && IsKeyPressed(ImGuiKey_Tab);
|
||||||
if (start_windowing_with_gamepad || start_windowing_with_keyboard)
|
if (start_windowing_with_gamepad || start_windowing_with_keyboard)
|
||||||
if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1))
|
if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1))
|
||||||
@@ -11428,7 +11429,7 @@ static void ImGui::NavUpdateWindowing()
|
|||||||
g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingTimer - NAV_WINDOWING_HIGHLIGHT_DELAY) / 0.05f));
|
g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingTimer - NAV_WINDOWING_HIGHLIGHT_DELAY) / 0.05f));
|
||||||
|
|
||||||
// Select window to focus
|
// Select window to focus
|
||||||
const int focus_change_dir = (int)IsNavInputTest(ImGuiNavInput_FocusPrev, ImGuiInputReadMode_RepeatSlow) - (int)IsNavInputTest(ImGuiNavInput_FocusNext, ImGuiInputReadMode_RepeatSlow);
|
const int focus_change_dir = (int)IsNavInputTest(ImGuiNavInput_FocusPrev, ImGuiNavReadMode_RepeatSlow) - (int)IsNavInputTest(ImGuiNavInput_FocusNext, ImGuiNavReadMode_RepeatSlow);
|
||||||
if (focus_change_dir != 0)
|
if (focus_change_dir != 0)
|
||||||
{
|
{
|
||||||
NavUpdateWindowingHighlightWindow(focus_change_dir);
|
NavUpdateWindowingHighlightWindow(focus_change_dir);
|
||||||
@@ -11489,9 +11490,9 @@ static void ImGui::NavUpdateWindowing()
|
|||||||
{
|
{
|
||||||
ImVec2 move_delta;
|
ImVec2 move_delta;
|
||||||
if (g.NavInputSource == ImGuiInputSource_Keyboard && !io.KeyShift)
|
if (g.NavInputSource == ImGuiInputSource_Keyboard && !io.KeyShift)
|
||||||
move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_RawKeyboard, ImGuiInputReadMode_Down);
|
move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_RawKeyboard, ImGuiNavReadMode_Down);
|
||||||
if (g.NavInputSource == ImGuiInputSource_Gamepad)
|
if (g.NavInputSource == ImGuiInputSource_Gamepad)
|
||||||
move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down);
|
move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiNavReadMode_Down);
|
||||||
if (move_delta.x != 0.0f || move_delta.y != 0.0f)
|
if (move_delta.x != 0.0f || move_delta.y != 0.0f)
|
||||||
{
|
{
|
||||||
const float NAV_MOVE_SPEED = 800.0f;
|
const float NAV_MOVE_SPEED = 800.0f;
|
||||||
|
2
imgui.h
2
imgui.h
@@ -65,7 +65,7 @@ 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.88 WIP"
|
#define IMGUI_VERSION "1.88 WIP"
|
||||||
#define IMGUI_VERSION_NUM 18718
|
#define IMGUI_VERSION_NUM 18719
|
||||||
#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_TABLE
|
#define IMGUI_HAS_TABLE
|
||||||
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
|
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
|
||||||
|
@@ -1241,14 +1241,14 @@ struct ImGuiInputEvent
|
|||||||
};
|
};
|
||||||
|
|
||||||
// FIXME-NAV: Clarify/expose various repeat delay/rate
|
// FIXME-NAV: Clarify/expose various repeat delay/rate
|
||||||
enum ImGuiInputReadMode
|
enum ImGuiNavReadMode
|
||||||
{
|
{
|
||||||
ImGuiInputReadMode_Down,
|
ImGuiNavReadMode_Down,
|
||||||
ImGuiInputReadMode_Pressed,
|
ImGuiNavReadMode_Pressed,
|
||||||
ImGuiInputReadMode_Released,
|
ImGuiNavReadMode_Released,
|
||||||
ImGuiInputReadMode_Repeat,
|
ImGuiNavReadMode_Repeat,
|
||||||
ImGuiInputReadMode_RepeatSlow,
|
ImGuiNavReadMode_RepeatSlow,
|
||||||
ImGuiInputReadMode_RepeatFast
|
ImGuiNavReadMode_RepeatFast
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -2576,6 +2576,7 @@ struct IMGUI_API ImGuiTable
|
|||||||
float InnerWidth; // User value passed to BeginTable(), see comments at the top of BeginTable() for details.
|
float InnerWidth; // User value passed to BeginTable(), see comments at the top of BeginTable() for details.
|
||||||
float ColumnsGivenWidth; // Sum of current column width
|
float ColumnsGivenWidth; // Sum of current column width
|
||||||
float ColumnsAutoFitWidth; // Sum of ideal column width in order nothing to be clipped, used for auto-fitting and content width submission in outer window
|
float ColumnsAutoFitWidth; // Sum of ideal column width in order nothing to be clipped, used for auto-fitting and content width submission in outer window
|
||||||
|
float ColumnsStretchSumWeights; // Sum of weight of all enabled stretching columns
|
||||||
float ResizedColumnNextWidth;
|
float ResizedColumnNextWidth;
|
||||||
float ResizeLockMinContentsX2; // Lock minimum contents width while resizing down in order to not create feedback loops. But we allow growing the table.
|
float ResizeLockMinContentsX2; // Lock minimum contents width while resizing down in order to not create feedback loops. But we allow growing the table.
|
||||||
float RefScale; // Reference scale to be able to rescale columns on font/dpi changes.
|
float RefScale; // Reference scale to be able to rescale columns on font/dpi changes.
|
||||||
@@ -2886,8 +2887,8 @@ namespace ImGui
|
|||||||
IMGUI_API void NavMoveRequestApplyResult();
|
IMGUI_API void NavMoveRequestApplyResult();
|
||||||
IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags);
|
IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags);
|
||||||
IMGUI_API const char* GetNavInputName(ImGuiNavInput n);
|
IMGUI_API const char* GetNavInputName(ImGuiNavInput n);
|
||||||
IMGUI_API float GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode);
|
IMGUI_API float GetNavInputAmount(ImGuiNavInput n, ImGuiNavReadMode mode);
|
||||||
IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f);
|
IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiNavReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f);
|
||||||
IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate);
|
IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate);
|
||||||
IMGUI_API void ActivateItem(ImGuiID id); // Remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again.
|
IMGUI_API void ActivateItem(ImGuiID id); // Remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again.
|
||||||
IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);
|
IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);
|
||||||
@@ -2914,7 +2915,7 @@ namespace ImGui
|
|||||||
inline void SetActiveIdUsingKey(ImGuiKey key) { ImGuiContext& g = *GImGui; g.ActiveIdUsingKeyInputMask.SetBit(key); }
|
inline void SetActiveIdUsingKey(ImGuiKey key) { ImGuiContext& g = *GImGui; g.ActiveIdUsingKeyInputMask.SetBit(key); }
|
||||||
IMGUI_API bool IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold = -1.0f);
|
IMGUI_API bool IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold = -1.0f);
|
||||||
inline bool IsNavInputDown(ImGuiNavInput n) { ImGuiContext& g = *GImGui; return g.IO.NavInputs[n] > 0.0f; }
|
inline bool IsNavInputDown(ImGuiNavInput n) { ImGuiContext& g = *GImGui; return g.IO.NavInputs[n] > 0.0f; }
|
||||||
inline bool IsNavInputTest(ImGuiNavInput n, ImGuiInputReadMode rm) { return (GetNavInputAmount(n, rm) > 0.0f); }
|
inline bool IsNavInputTest(ImGuiNavInput n, ImGuiNavReadMode rm) { return (GetNavInputAmount(n, rm) > 0.0f); }
|
||||||
IMGUI_API ImGuiModFlags GetMergedModFlags();
|
IMGUI_API ImGuiModFlags GetMergedModFlags();
|
||||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||||
inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { IM_ASSERT(IsNamedKey(key)); return IsKeyPressed(key, repeat); } // [removed in 1.87]
|
inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { IM_ASSERT(IsNamedKey(key)); return IsKeyPressed(key, repeat); } // [removed in 1.87]
|
||||||
|
@@ -888,6 +888,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
sum_width_requests += table->CellPaddingX * 2.0f;
|
sum_width_requests += table->CellPaddingX * 2.0f;
|
||||||
}
|
}
|
||||||
table->ColumnsEnabledFixedCount = (ImGuiTableColumnIdx)count_fixed;
|
table->ColumnsEnabledFixedCount = (ImGuiTableColumnIdx)count_fixed;
|
||||||
|
table->ColumnsStretchSumWeights = stretch_sum_weights;
|
||||||
|
|
||||||
// [Part 4] Apply final widths based on requested widths
|
// [Part 4] Apply final widths based on requested widths
|
||||||
const ImRect work_rect = table->WorkRect;
|
const ImRect work_rect = table->WorkRect;
|
||||||
@@ -1284,17 +1285,23 @@ void ImGui::EndTable()
|
|||||||
splitter->Merge(inner_window->DrawList);
|
splitter->Merge(inner_window->DrawList);
|
||||||
|
|
||||||
// Update ColumnsAutoFitWidth to get us ahead for host using our size to auto-resize without waiting for next BeginTable()
|
// Update ColumnsAutoFitWidth to get us ahead for host using our size to auto-resize without waiting for next BeginTable()
|
||||||
const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1);
|
float auto_fit_width_for_fixed = 0.0f;
|
||||||
table->ColumnsAutoFitWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount;
|
float auto_fit_width_for_stretched = 0.0f;
|
||||||
|
float auto_fit_width_for_stretched_min = 0.0f;
|
||||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||||
if (table->EnabledMaskByIndex & ((ImU64)1 << column_n))
|
if (table->EnabledMaskByIndex & ((ImU64)1 << column_n))
|
||||||
{
|
{
|
||||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !(column->Flags & ImGuiTableColumnFlags_NoResize))
|
float column_width_request = ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !(column->Flags & ImGuiTableColumnFlags_NoResize)) ? column->WidthRequest : TableGetColumnWidthAuto(table, column);
|
||||||
table->ColumnsAutoFitWidth += column->WidthRequest;
|
if (column->Flags & ImGuiTableColumnFlags_WidthFixed)
|
||||||
|
auto_fit_width_for_fixed += column_width_request;
|
||||||
else
|
else
|
||||||
table->ColumnsAutoFitWidth += TableGetColumnWidthAuto(table, column);
|
auto_fit_width_for_stretched += column_width_request;
|
||||||
|
if ((column->Flags & ImGuiTableColumnFlags_WidthStretch) && (column->Flags & ImGuiTableColumnFlags_NoResize) != 0)
|
||||||
|
auto_fit_width_for_stretched_min = ImMax(auto_fit_width_for_stretched_min, column_width_request / (column->StretchWeight / table->ColumnsStretchSumWeights));
|
||||||
}
|
}
|
||||||
|
const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1);
|
||||||
|
table->ColumnsAutoFitWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount + auto_fit_width_for_fixed + ImMax(auto_fit_width_for_stretched, auto_fit_width_for_stretched_min);
|
||||||
|
|
||||||
// Update scroll
|
// Update scroll
|
||||||
if ((table->Flags & ImGuiTableFlags_ScrollX) == 0 && inner_window != outer_window)
|
if ((table->Flags & ImGuiTableFlags_ScrollX) == 0 && inner_window != outer_window)
|
||||||
|
@@ -609,7 +609,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|||||||
if (g.NavActivateDownId == id)
|
if (g.NavActivateDownId == id)
|
||||||
{
|
{
|
||||||
bool nav_activated_by_code = (g.NavActivateId == id);
|
bool nav_activated_by_code = (g.NavActivateId == id);
|
||||||
bool nav_activated_by_inputs = IsNavInputTest(ImGuiNavInput_Activate, (flags & ImGuiButtonFlags_Repeat) ? ImGuiInputReadMode_Repeat : ImGuiInputReadMode_Pressed);
|
bool nav_activated_by_inputs = IsNavInputTest(ImGuiNavInput_Activate, (flags & ImGuiButtonFlags_Repeat) ? ImGuiNavReadMode_Repeat : ImGuiNavReadMode_Pressed);
|
||||||
if (nav_activated_by_code || nav_activated_by_inputs)
|
if (nav_activated_by_code || nav_activated_by_inputs)
|
||||||
{
|
{
|
||||||
// Set active id so it can be queried by user via IsItemActive(), equivalent of holding the mouse button.
|
// Set active id so it can be queried by user via IsItemActive(), equivalent of holding the mouse button.
|
||||||
@@ -2184,7 +2184,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
|
|||||||
else if (g.ActiveIdSource == ImGuiInputSource_Nav)
|
else if (g.ActiveIdSource == ImGuiInputSource_Nav)
|
||||||
{
|
{
|
||||||
const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0;
|
const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0;
|
||||||
adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f / 10.0f, 10.0f)[axis];
|
adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiNavReadMode_RepeatFast, 1.0f / 10.0f, 10.0f)[axis];
|
||||||
v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision));
|
v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision));
|
||||||
}
|
}
|
||||||
adjust_delta *= v_speed;
|
adjust_delta *= v_speed;
|
||||||
@@ -2788,7 +2788,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
|||||||
g.SliderCurrentAccumDirty = false;
|
g.SliderCurrentAccumDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ImVec2 input_delta2 = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 0.0f, 0.0f);
|
const ImVec2 input_delta2 = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiNavReadMode_RepeatFast, 0.0f, 0.0f);
|
||||||
float input_delta = (axis == ImGuiAxis_X) ? input_delta2.x : -input_delta2.y;
|
float input_delta = (axis == ImGuiAxis_X) ? input_delta2.x : -input_delta2.y;
|
||||||
if (input_delta != 0.0f)
|
if (input_delta != 0.0f)
|
||||||
{
|
{
|
||||||
@@ -4298,8 +4298,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
|
|
||||||
// We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it isn't very useful.
|
// We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it isn't very useful.
|
||||||
const bool is_validate_enter = IsKeyPressed(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_KeypadEnter);
|
const bool is_validate_enter = IsKeyPressed(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_KeypadEnter);
|
||||||
const bool is_validate_nav = (IsNavInputTest(ImGuiNavInput_Activate, ImGuiInputReadMode_Pressed) && !IsKeyPressed(ImGuiKey_Space)) || IsNavInputTest(ImGuiNavInput_Input, ImGuiInputReadMode_Pressed);
|
const bool is_validate_nav = (IsNavInputTest(ImGuiNavInput_Activate, ImGuiNavReadMode_Pressed) && !IsKeyPressed(ImGuiKey_Space)) || IsNavInputTest(ImGuiNavInput_Input, ImGuiNavReadMode_Pressed);
|
||||||
const bool is_cancel = IsKeyPressed(ImGuiKey_Escape) || IsNavInputTest(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed);
|
const bool is_cancel = IsKeyPressed(ImGuiKey_Escape) || IsNavInputTest(ImGuiNavInput_Cancel, ImGuiNavReadMode_Pressed);
|
||||||
|
|
||||||
if (IsKeyPressed(ImGuiKey_LeftArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); }
|
if (IsKeyPressed(ImGuiKey_LeftArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); }
|
||||||
else if (IsKeyPressed(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); }
|
else if (IsKeyPressed(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); }
|
||||||
|
Reference in New Issue
Block a user