mirror of
https://github.com/ocornut/imgui.git
synced 2024-12-01 02:37:24 +01:00
Merge branch 'master' into docking
# Conflicts: # backends/imgui_impl_metal.mm # imgui.cpp # imgui.h
This commit is contained in:
commit
e900ca355e
@ -14,6 +14,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-XX-XX: Metal: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2022-06-01: Metal: Fixed null dereference on exit inside command buffer completion handler.
|
||||
// 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).
|
||||
// 2021-12-30: Metal: Added Metal C++ support. Enable with '#define IMGUI_IMPL_METAL_CPP' in your imconfig.h file.
|
||||
@ -306,8 +307,11 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||
[bd->SharedMetalContext.bufferCache addObject:vertexBuffer];
|
||||
[bd->SharedMetalContext.bufferCache addObject:indexBuffer];
|
||||
if (bd != NULL)
|
||||
{
|
||||
[bd->SharedMetalContext.bufferCache addObject:vertexBuffer];
|
||||
[bd->SharedMetalContext.bufferCache addObject:indexBuffer];
|
||||
}
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
@ -132,6 +132,9 @@ Other Changes:
|
||||
or interacting with a game/3D view).
|
||||
- IO: Fixed input queue trickling of mouse wheel events: multiple wheel events are merged, while
|
||||
a mouse pos followed by a mouse wheel are now trickled. (#4921, #4821)
|
||||
- IO: Added io.SetAppAcceptingEvents() to set a master flag for accepting key/mouse/characters
|
||||
events (default to true). Useful if you have native dialog boxes that are interrupting your
|
||||
application loop/refresh, and you want to disable events being queued while your app is frozen.
|
||||
- Windows: Fixed first-time windows appearing in negative coordinates from being initialized
|
||||
with a wrong size. This would most often be noticeable in multi-viewport mode (docking branch)
|
||||
when spawning a window in a monitor with negative coordinates. (#5215, #3414) [@DimaKoltun]
|
||||
@ -146,20 +149,29 @@ Other Changes:
|
||||
- InputScalar: Automatically allow hexadecimal input when format is %X (without extra flag).
|
||||
- InputScalar: Automatically allow scientific input when format is float/double (without extra flag).
|
||||
- Nav: Fixed nav movement in a scope with only one disabled item from focusing the disabled item. (#5189)
|
||||
- Nav: Fixed issues with nav request being transferred to another window when calling SetKeyboardFocusHere()
|
||||
and simultaneous changing window focus. (#4449)
|
||||
- IsItemHovered(): added ImGuiHoveredFlags_NoNavOverride to disable the behavior where the
|
||||
return value is overriden by focus when gamepad/keyboard navigation is active.
|
||||
- InputText: Fixed pressing Tab emitting two tabs characters because of dual Keys/Chars events being
|
||||
trickled with the new input queue (happened on some backends only). (#2467, #1336)
|
||||
- InputText: Fixed a one-frame display glitch where pressing Escape to revert after a deletion
|
||||
would lead to small garbage being displayed for one frame. Curiously a rather old bug! (#3008)
|
||||
- InputText: Fixed an undo-state corruption issue when editing main buffer before reactivating item. (#4947)
|
||||
- InputText: Fixed an undo-state corruption issue when editing in-flight buffer in user callback.
|
||||
(#4947, #4949] [@JoshuaWebb]
|
||||
- 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).
|
||||
- Tables: Fixed incorrect auto-fit of parent windows when using non-resizable weighted columns. (#5276)
|
||||
- Tables: Fixed drawcall merging of last column. Depending on some unrelated settings (e.g. BorderH)
|
||||
merging drawcall of the last column didn't always work (regression since 1.87). (#4843, #4844) [@rokups]
|
||||
- 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.
|
||||
- Menus: Adjusted BeginMenu() closing logic so hovering void or non-MenuItem() in parent window
|
||||
always lead to menu closure. Fixes using items that are not MenuItem() or BeginItem() at the root
|
||||
level of a popup with a child menu opened.
|
||||
- Menus: Menus emitted from the main/scrolling layer are not part of the same menuset as menus emitted
|
||||
from the menu-bar, avoiding accidental hovering from one to the other. (#3496, #4797) [@rokups]
|
||||
- Stack Tool: Added option to copy item path to clipboard. (#4631)
|
||||
- Settings: Fixed out-of-bounds read when .ini file on disk is empty. (#5351) [@quantum5]
|
||||
- DrawList: Fixed PathArcTo() emitting terminating vertices too close to arc vertices. (#4993) [@thedmd]
|
||||
@ -170,6 +182,7 @@ Other Changes:
|
||||
you have a UTF-8 text encoding issue or a font loading issue. [@LaMarche05, @ocornut]
|
||||
- Demo: Add better demo of how to use SetNextFrameWantCaptureMouse()/SetNextFrameWantCaptureKeyboard().
|
||||
- Metrics: Added a "UTF-8 Encoding Viewer" section using the aforementioned DebugTextEncoding() function.
|
||||
- Metrics: Added "InputText" section to visualize internal state (#4947, #4949).
|
||||
- Misc: Fixed calling GetID("label") _before_ a widget emitting this item inside a group (such as InputInt())
|
||||
from causing an assertion when closing the group. (#5181).
|
||||
- Misc: Fixed IsAnyItemHovered() returning false when using navigation.
|
||||
@ -191,6 +204,7 @@ Other Changes:
|
||||
- Backends: OSX: Monitor NSKeyUp events to catch missing keyUp for key when user press Cmd + key (#5128) [@thedmd]
|
||||
- Backends: OSX, Metal: Store backend data in a per-context struct, allowing to use these backends with
|
||||
multiple contexts. (#5203, #5221, #4141) [@noisewuwei]
|
||||
- Backends: Metal: Fixed null dereference on exit inside command buffer completion handler. (#5363, #5365) [@warrenm]
|
||||
- Backends: OpenGL3: Partially revert 1.86 change of using glBufferSubData(): now only done on Windows and
|
||||
Intel GPU, based on querying glGetString(GL_VENDOR). Essentially we got report of accumulating leaks on Intel
|
||||
with multi-viewports when using simple glBufferData() without orphaning, and report of corruptions on other
|
||||
|
91
imgui.cpp
91
imgui.cpp
@ -1205,6 +1205,7 @@ ImGuiIO::ImGuiIO()
|
||||
for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f;
|
||||
for (int i = 0; i < IM_ARRAYSIZE(KeysData); i++) { KeysData[i].DownDuration = KeysData[i].DownDurationPrev = -1.0f; }
|
||||
for (int i = 0; i < IM_ARRAYSIZE(NavInputsDownDuration); i++) NavInputsDownDuration[i] = -1.0f;
|
||||
AppAcceptingEvents = true;
|
||||
BackendUsingLegacyKeyArrays = (ImS8)-1;
|
||||
BackendUsingLegacyNavInputArray = true; // assume using legacy array until proven wrong
|
||||
}
|
||||
@ -1217,7 +1218,7 @@ void ImGuiIO::AddInputCharacter(unsigned int c)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
|
||||
if (c == 0)
|
||||
if (c == 0 || !AppAcceptingEvents)
|
||||
return;
|
||||
|
||||
ImGuiInputEvent e;
|
||||
@ -1231,7 +1232,7 @@ void ImGuiIO::AddInputCharacter(unsigned int c)
|
||||
// we should save the high surrogate.
|
||||
void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c)
|
||||
{
|
||||
if (c == 0 && InputQueueSurrogate == 0)
|
||||
if ((c == 0 && InputQueueSurrogate == 0) || !AppAcceptingEvents)
|
||||
return;
|
||||
|
||||
if ((c & 0xFC00) == 0xD800) // High surrogate, must save
|
||||
@ -1265,6 +1266,8 @@ void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c)
|
||||
|
||||
void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars)
|
||||
{
|
||||
if (!AppAcceptingEvents)
|
||||
return;
|
||||
while (*utf8_chars != 0)
|
||||
{
|
||||
unsigned int c = 0;
|
||||
@ -1303,7 +1306,7 @@ void ImGuiIO::ClearInputKeys()
|
||||
void ImGuiIO::AddKeyAnalogEvent(ImGuiKey key, bool down, float analog_value)
|
||||
{
|
||||
//if (e->Down) { IMGUI_DEBUG_LOG("AddKeyEvent() Key='%s' %d, NativeKeycode = %d, NativeScancode = %d\n", ImGui::GetKeyName(e->Key), e->Down, e->NativeKeycode, e->NativeScancode); }
|
||||
if (key == ImGuiKey_None)
|
||||
if (key == ImGuiKey_None || !AppAcceptingEvents)
|
||||
return;
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
|
||||
@ -1344,6 +1347,8 @@ void ImGuiIO::AddKeyAnalogEvent(ImGuiKey key, bool down, float analog_value)
|
||||
|
||||
void ImGuiIO::AddKeyEvent(ImGuiKey key, bool down)
|
||||
{
|
||||
if (!AppAcceptingEvents)
|
||||
return;
|
||||
AddKeyAnalogEvent(key, down, down ? 1.0f : 0.0f);
|
||||
}
|
||||
|
||||
@ -1372,11 +1377,19 @@ void ImGuiIO::SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set master flag for accepting key/mouse/text events (default to true). Useful if you have native dialog boxes that are interrupting your application loop/refresh, and you want to disable events being queued while your app is frozen.
|
||||
void ImGuiIO::SetAppAcceptingEvents(bool accepting_events)
|
||||
{
|
||||
AppAcceptingEvents = accepting_events;
|
||||
}
|
||||
|
||||
// Queue a mouse move event
|
||||
void ImGuiIO::AddMousePosEvent(float x, float y)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
|
||||
if (!AppAcceptingEvents)
|
||||
return;
|
||||
|
||||
ImGuiInputEvent e;
|
||||
e.Type = ImGuiInputEventType_MousePos;
|
||||
@ -1391,6 +1404,8 @@ void ImGuiIO::AddMouseButtonEvent(int mouse_button, bool down)
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
|
||||
IM_ASSERT(mouse_button >= 0 && mouse_button < ImGuiMouseButton_COUNT);
|
||||
if (!AppAcceptingEvents)
|
||||
return;
|
||||
|
||||
ImGuiInputEvent e;
|
||||
e.Type = ImGuiInputEventType_MouseButton;
|
||||
@ -1405,7 +1420,7 @@ void ImGuiIO::AddMouseWheelEvent(float wheel_x, float wheel_y)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
|
||||
if (wheel_x == 0.0f && wheel_y == 0.0f)
|
||||
if ((wheel_x == 0.0f && wheel_y == 0.0f) || !AppAcceptingEvents)
|
||||
return;
|
||||
|
||||
ImGuiInputEvent e;
|
||||
@ -1738,6 +1753,25 @@ int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args)
|
||||
}
|
||||
#endif // #ifdef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS
|
||||
|
||||
void ImFormatStringToTempBuffer(const char** out_buf, const char** out_buf_end, const char* fmt, ...)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int buf_len = ImFormatStringV(g.TempBuffer.Data, g.TempBuffer.Size, fmt, args);
|
||||
*out_buf = g.TempBuffer.Data;
|
||||
if (out_buf_end) { *out_buf_end = g.TempBuffer.Data + buf_len; }
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void ImFormatStringToTempBufferV(const char** out_buf, const char** out_buf_end, const char* fmt, va_list args)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
int buf_len = ImFormatStringV(g.TempBuffer.Data, g.TempBuffer.Size, fmt, args);
|
||||
*out_buf = g.TempBuffer.Data;
|
||||
if (out_buf_end) { *out_buf_end = g.TempBuffer.Data + buf_len; }
|
||||
}
|
||||
|
||||
// CRC32 needs a 1KB lookup table (not cache friendly)
|
||||
// Although the code to generate the table is simple and shorter than the table itself, using a const table allows us to easily:
|
||||
// - avoid an unnecessary branch/memory tap, - keep the ImHashXXX functions usable by static constructors, - make it thread-safe.
|
||||
@ -4640,6 +4674,7 @@ void ImGui::Initialize()
|
||||
viewport->PlatformWindowCreated = true;
|
||||
viewport->Flags = ImGuiViewportFlags_OwnedByApp;
|
||||
g.Viewports.push_back(viewport);
|
||||
g.TempBuffer.resize(1024 * 3 + 1, 0);
|
||||
g.PlatformIO.Viewports.push_back(g.Viewports[0]);
|
||||
|
||||
#ifdef IMGUI_HAS_DOCK
|
||||
@ -5424,15 +5459,16 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
|
||||
SetNextWindowSize(size);
|
||||
|
||||
// Build up name. If you need to append to a same child from multiple location in the ID stack, use BeginChild(ImGuiID id) with a stable value.
|
||||
const char* temp_window_name;
|
||||
if (name)
|
||||
ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%s_%08X", parent_window->Name, name, id);
|
||||
ImFormatStringToTempBuffer(&temp_window_name, NULL, "%s/%s_%08X", parent_window->Name, name, id);
|
||||
else
|
||||
ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%08X", parent_window->Name, id);
|
||||
ImFormatStringToTempBuffer(&temp_window_name, NULL, "%s/%08X", parent_window->Name, id);
|
||||
|
||||
const float backup_border_size = g.Style.ChildBorderSize;
|
||||
if (!border)
|
||||
g.Style.ChildBorderSize = 0.0f;
|
||||
bool ret = Begin(g.TempBuffer, NULL, flags);
|
||||
bool ret = Begin(temp_window_name, NULL, flags);
|
||||
g.Style.ChildBorderSize = backup_border_size;
|
||||
|
||||
ImGuiWindow* child_window = g.CurrentWindow;
|
||||
@ -6432,6 +6468,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
{
|
||||
ImGuiPopupData& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size];
|
||||
popup_ref.Window = window;
|
||||
popup_ref.ParentNavLayer = parent_window_in_stack->DC.NavLayerCurrent;
|
||||
g.BeginPopupStack.push_back(popup_ref);
|
||||
window->PopupId = popup_ref.PopupId;
|
||||
}
|
||||
@ -7942,7 +7979,10 @@ void ImGui::SetKeyboardFocusHere(int offset)
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
IM_ASSERT(offset >= -1); // -1 is allowed but not below
|
||||
|
||||
g.NavWindow = window;
|
||||
g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false;
|
||||
|
||||
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
|
||||
NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_FocusApi, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
|
||||
if (offset == -1)
|
||||
@ -10190,8 +10230,11 @@ void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window)
|
||||
// Note that window may be != g.CurrentWindow (e.g. SetFocusID call in InputTextEx for multi-line text)
|
||||
const ImGuiNavLayer nav_layer = window->DC.NavLayerCurrent;
|
||||
if (g.NavWindow != window)
|
||||
g.NavInitRequest = false;
|
||||
g.NavWindow = window;
|
||||
{
|
||||
g.NavWindow = window;
|
||||
g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false;
|
||||
NavUpdateAnyRequestFlag();
|
||||
}
|
||||
g.NavId = id;
|
||||
g.NavLayer = nav_layer;
|
||||
g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
|
||||
@ -10439,7 +10482,12 @@ static void ImGui::NavProcessItem()
|
||||
// Update window-relative bounding box of navigated item
|
||||
if (g.NavId == id)
|
||||
{
|
||||
g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window.
|
||||
if (g.NavWindow != window)
|
||||
{
|
||||
g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window.
|
||||
g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false;
|
||||
NavUpdateAnyRequestFlag();
|
||||
}
|
||||
g.NavLayer = window->DC.NavLayerCurrent;
|
||||
g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
|
||||
g.NavIdIsAlive = true;
|
||||
@ -10517,10 +10565,11 @@ void ImGui::NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavM
|
||||
g.NavMoveScrollFlags = scroll_flags;
|
||||
g.NavMoveForwardToNextFrame = false;
|
||||
g.NavMoveKeyMods = g.IO.KeyMods;
|
||||
g.NavTabbingCounter = 0;
|
||||
g.NavMoveResultLocal.Clear();
|
||||
g.NavMoveResultLocalVisible.Clear();
|
||||
g.NavMoveResultOther.Clear();
|
||||
g.NavTabbingCounter = 0;
|
||||
g.NavTabbingResultFirst.Clear();
|
||||
NavUpdateAnyRequestFlag();
|
||||
}
|
||||
|
||||
@ -10590,7 +10639,7 @@ void ImGui::NavRestoreLayer(ImGuiNavLayer layer)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (layer == ImGuiNavLayer_Main)
|
||||
g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow);
|
||||
g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow); // FIXME-NAV: Should clear ongoing nav requests?
|
||||
ImGuiWindow* window = g.NavWindow;
|
||||
if (window->NavLastIds[layer] != 0)
|
||||
{
|
||||
@ -11071,7 +11120,6 @@ void ImGui::NavUpdateCreateTabbingRequest()
|
||||
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
|
||||
ImGuiDir clip_dir = (g.NavTabbingDir < 0) ? ImGuiDir_Up : ImGuiDir_Down;
|
||||
NavMoveRequestSubmit(ImGuiDir_None, clip_dir, ImGuiNavMoveFlags_Tabbing, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
|
||||
g.NavTabbingResultFirst.Clear();
|
||||
g.NavTabbingCounter = -1;
|
||||
}
|
||||
|
||||
@ -17954,6 +18002,13 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
TreePop();
|
||||
}
|
||||
|
||||
// Details for InputText
|
||||
if (TreeNode("InputText"))
|
||||
{
|
||||
DebugNodeInputTextState(&g.InputTextState);
|
||||
TreePop();
|
||||
}
|
||||
|
||||
// Details for Docking
|
||||
#ifdef IMGUI_HAS_DOCK
|
||||
if (TreeNode("Docking"))
|
||||
@ -18840,8 +18895,8 @@ void ImGui::ShowStackToolWindow(bool* p_open)
|
||||
if (tool->CopyToClipboardOnCtrlC && IsKeyDown(ImGuiKey_ModCtrl) && IsKeyPressed(ImGuiKey_C))
|
||||
{
|
||||
tool->CopyToClipboardLastTime = (float)g.Time;
|
||||
char* p = g.TempBuffer;
|
||||
char* p_end = p + IM_ARRAYSIZE(g.TempBuffer);
|
||||
char* p = g.TempBuffer.Data;
|
||||
char* p_end = p + g.TempBuffer.Size;
|
||||
for (int stack_n = 0; stack_n < tool->Results.Size && p + 3 < p_end; stack_n++)
|
||||
{
|
||||
*p++ = '/';
|
||||
@ -18855,7 +18910,7 @@ void ImGui::ShowStackToolWindow(bool* p_open)
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
SetClipboardText(g.TempBuffer);
|
||||
SetClipboardText(g.TempBuffer.Data);
|
||||
}
|
||||
|
||||
// Display decorated stack
|
||||
@ -18873,8 +18928,8 @@ void ImGui::ShowStackToolWindow(bool* p_open)
|
||||
TableNextColumn();
|
||||
Text("0x%08X", (n > 0) ? tool->Results[n - 1].ID : 0);
|
||||
TableNextColumn();
|
||||
StackToolFormatLevelInfo(tool, n, true, g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer));
|
||||
TextUnformatted(g.TempBuffer);
|
||||
StackToolFormatLevelInfo(tool, n, true, g.TempBuffer.Data, g.TempBuffer.Size);
|
||||
TextUnformatted(g.TempBuffer.Data);
|
||||
TableNextColumn();
|
||||
Text("0x%08X", info->ID);
|
||||
if (n == tool->Results.Size - 1)
|
||||
|
24
imgui.h
24
imgui.h
@ -65,7 +65,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.88 WIP"
|
||||
#define IMGUI_VERSION_NUM 18724
|
||||
#define IMGUI_VERSION_NUM 18728
|
||||
#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_VIEWPORT // Viewport WIP branch
|
||||
@ -1402,6 +1402,8 @@ enum ImGuiSortDirection_
|
||||
ImGuiSortDirection_Descending = 2 // Descending = 9->0, Z->A etc.
|
||||
};
|
||||
|
||||
// Keys value 0 to 511 are left unused as legacy native/opaque key values (< 1.87)
|
||||
// Keys value >= 512 are named keys (>= 1.87)
|
||||
enum ImGuiKey_
|
||||
{
|
||||
// Keyboard
|
||||
@ -1502,10 +1504,10 @@ enum ImGuiKey_
|
||||
ImGuiKey_NamedKey_COUNT = ImGuiKey_NamedKey_END - ImGuiKey_NamedKey_BEGIN,
|
||||
#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
ImGuiKey_KeysData_SIZE = ImGuiKey_NamedKey_COUNT, // Size of KeysData[]: only hold named keys
|
||||
ImGuiKey_KeysData_OFFSET = ImGuiKey_NamedKey_BEGIN // First key stored in KeysData[0]
|
||||
ImGuiKey_KeysData_OFFSET = ImGuiKey_NamedKey_BEGIN // First key stored in io.KeysData[0]. Accesses to io.KeysData[] must use (key - ImGuiKey_KeysData_OFFSET).
|
||||
#else
|
||||
ImGuiKey_KeysData_SIZE = ImGuiKey_COUNT, // Size of KeysData[]: hold legacy 0..512 keycodes + named keys
|
||||
ImGuiKey_KeysData_OFFSET = 0 // First key stored in KeysData[0]
|
||||
ImGuiKey_KeysData_OFFSET = 0 // First key stored in io.KeysData[0]. Accesses to io.KeysData[] must use (key - ImGuiKey_KeysData_OFFSET).
|
||||
#endif
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
@ -1524,6 +1526,7 @@ enum ImGuiModFlags_
|
||||
};
|
||||
|
||||
// Gamepad/Keyboard navigation
|
||||
// Since >= 1.87 backends you generally don't need to care about this enum since io.NavInputs[] is setup automatically. This might become private/internal some day.
|
||||
// Keyboard: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.AddKeyEvent() calls.
|
||||
// Gamepad: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. Backend: set ImGuiBackendFlags_HasGamepad and fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame().
|
||||
// Read instructions in imgui.cpp for more details. Download PNG/PSD at http://dearimgui.org/controls_sheets.
|
||||
@ -1576,7 +1579,7 @@ enum ImGuiConfigFlags_
|
||||
ImGuiConfigFlags_DpiEnableScaleViewports= 1 << 14, // [BETA: Don't use] FIXME-DPI: Reposition and resize imgui windows when the DpiScale of a viewport changed (mostly useful for the main viewport hosting other window). Note that resizing the main window itself is up to your application.
|
||||
ImGuiConfigFlags_DpiEnableScaleFonts = 1 << 15, // [BETA: Don't use] FIXME-DPI: Request bitmap-scaled fonts to match DpiScale. This is a very low-quality workaround. The correct way to handle DPI is _currently_ to replace the atlas and/or fonts in the Platform_OnChangedViewport callback, but this is all early work in progress.
|
||||
|
||||
// User storage (to allow your backend/engine to communicate to code that may be shared between multiple projects. Those flags are not used by core Dear ImGui)
|
||||
// User storage (to allow your backend/engine to communicate to code that may be shared between multiple projects. Those flags are NOT used by core Dear ImGui)
|
||||
ImGuiConfigFlags_IsSRGB = 1 << 20, // Application is SRGB-aware.
|
||||
ImGuiConfigFlags_IsTouchScreen = 1 << 21 // Application is using a touch screen instead of a mouse.
|
||||
};
|
||||
@ -1629,10 +1632,10 @@ enum ImGuiCol_
|
||||
ImGuiCol_Separator,
|
||||
ImGuiCol_SeparatorHovered,
|
||||
ImGuiCol_SeparatorActive,
|
||||
ImGuiCol_ResizeGrip,
|
||||
ImGuiCol_ResizeGrip, // Resize grip in lower-right and lower-left corners of windows.
|
||||
ImGuiCol_ResizeGripHovered,
|
||||
ImGuiCol_ResizeGripActive,
|
||||
ImGuiCol_Tab,
|
||||
ImGuiCol_Tab, // TabItem in a TabBar
|
||||
ImGuiCol_TabHovered,
|
||||
ImGuiCol_TabActive,
|
||||
ImGuiCol_TabUnfocused,
|
||||
@ -1649,7 +1652,7 @@ enum ImGuiCol_
|
||||
ImGuiCol_TableRowBg, // Table row background (even rows)
|
||||
ImGuiCol_TableRowBgAlt, // Table row background (odd rows)
|
||||
ImGuiCol_TextSelectedBg,
|
||||
ImGuiCol_DragDropTarget,
|
||||
ImGuiCol_DragDropTarget, // Rectangle highlighting a drop target
|
||||
ImGuiCol_NavHighlight, // Gamepad/keyboard: current highlighted item
|
||||
ImGuiCol_NavWindowingHighlight, // Highlight window when using CTRL+TAB
|
||||
ImGuiCol_NavWindowingDimBg, // Darken/colorize entire screen behind the CTRL+TAB window list, when active
|
||||
@ -1884,6 +1887,7 @@ struct ImVector
|
||||
inline void resize(int new_size, const T& v) { if (new_size > Capacity) reserve(_grow_capacity(new_size)); if (new_size > Size) for (int n = Size; n < new_size; n++) memcpy(&Data[n], &v, sizeof(v)); Size = new_size; }
|
||||
inline void shrink(int new_size) { IM_ASSERT(new_size <= Size); Size = new_size; } // Resize a vector to a smaller size, guaranteed not to cause a reallocation
|
||||
inline void reserve(int new_capacity) { if (new_capacity <= Capacity) return; T* new_data = (T*)IM_ALLOC((size_t)new_capacity * sizeof(T)); if (Data) { memcpy(new_data, Data, (size_t)Size * sizeof(T)); IM_FREE(Data); } Data = new_data; Capacity = new_capacity; }
|
||||
inline void reserve_discard(int new_capacity) { if (new_capacity <= Capacity) return; if (Data) IM_FREE(Data); Data = (T*)IM_ALLOC((size_t)new_capacity * sizeof(T)); Capacity = new_capacity; }
|
||||
|
||||
// NB: It is illegal to call push_back/push_front/insert with a reference pointing inside the ImVector data itself! e.g. v.push_back(v[10]) is forbidden.
|
||||
inline void push_back(const T& v) { if (Size == Capacity) reserve(_grow_capacity(Size + 1)); memcpy(&Data[Size], &v, sizeof(v)); Size++; }
|
||||
@ -2066,9 +2070,10 @@ struct ImGuiIO
|
||||
IMGUI_API void AddInputCharacterUTF16(ImWchar16 c); // Queue a new character input from an UTF-16 character, it can be a surrogate
|
||||
IMGUI_API void AddInputCharactersUTF8(const char* str); // Queue a new characters input from an UTF-8 string
|
||||
|
||||
IMGUI_API void SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native_scancode, int native_legacy_index = -1); // [Optional] Specify index for legacy <1.87 IsKeyXXX() functions with native indices + specify native keycode, scancode.
|
||||
IMGUI_API void SetAppAcceptingEvents(bool accepting_events); // Set master flag for accepting key/mouse/text events (default to true). Useful if you have native dialog boxes that are interrupting your application loop/refresh, and you want to disable events being queued while your app is frozen.
|
||||
IMGUI_API void ClearInputCharacters(); // [Internal] Clear the text input buffer manually
|
||||
IMGUI_API void ClearInputKeys(); // [Internal] Release all keys
|
||||
IMGUI_API void SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native_scancode, int native_legacy_index = -1); // [Optional] Specify index for legacy <1.87 IsKeyXXX() functions with native indices + specify native keycode, scancode.
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Output - Updated by NewFrame() or EndFrame()/Render()
|
||||
@ -2137,7 +2142,8 @@ struct ImGuiIO
|
||||
float NavInputsDownDuration[ImGuiNavInput_COUNT];
|
||||
float NavInputsDownDurationPrev[ImGuiNavInput_COUNT];
|
||||
float PenPressure; // Touch/Pen pressure (0.0f to 1.0f, should be >0.0f only when MouseDown[0] == true). Helper storage currently unused by Dear ImGui.
|
||||
bool AppFocusLost;
|
||||
bool AppFocusLost; // Only modify via AddFocusEvent()
|
||||
bool AppAcceptingEvents; // Only modify via SetAppAcceptingEvents()
|
||||
ImS8 BackendUsingLegacyKeyArrays; // -1: unknown, 0: using AddKeyEvent(), 1: using legacy io.KeysDown[]
|
||||
bool BackendUsingLegacyNavInputArray; // 0: using AddKeyAnalogEvent(), 1: writing to legacy io.NavInputs[] directly
|
||||
ImWchar16 InputQueueSurrogate; // For AddInputCharacterUTF16()
|
||||
|
@ -3275,59 +3275,58 @@ static void ShowDemoWindowLayout()
|
||||
ImGui::DragFloat2("size", (float*)&size, 0.5f, 1.0f, 200.0f, "%.0f");
|
||||
ImGui::TextWrapped("(Click and drag to scroll)");
|
||||
|
||||
HelpMarker(
|
||||
"(Left) Using ImGui::PushClipRect():\n"
|
||||
"Will alter ImGui hit-testing logic + ImDrawList rendering.\n"
|
||||
"(use this if you want your clipping rectangle to affect interactions)\n\n"
|
||||
"(Center) Using ImDrawList::PushClipRect():\n"
|
||||
"Will alter ImDrawList rendering only.\n"
|
||||
"(use this as a shortcut if you are only using ImDrawList calls)\n\n"
|
||||
"(Right) Using ImDrawList::AddText() with a fine ClipRect:\n"
|
||||
"Will alter only this specific ImDrawList::AddText() rendering.\n"
|
||||
"This is often used internally to avoid altering the clipping rectangle and minimize draw calls.");
|
||||
|
||||
for (int n = 0; n < 3; n++)
|
||||
{
|
||||
if (n > 0)
|
||||
ImGui::SameLine();
|
||||
ImGui::PushID(n);
|
||||
ImGui::BeginGroup(); // Lock X position
|
||||
|
||||
ImGui::InvisibleButton("##empty", size);
|
||||
ImGui::PushID(n);
|
||||
ImGui::InvisibleButton("##canvas", size);
|
||||
if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
{
|
||||
offset.x += ImGui::GetIO().MouseDelta.x;
|
||||
offset.y += ImGui::GetIO().MouseDelta.y;
|
||||
}
|
||||
ImGui::PopID();
|
||||
if (!ImGui::IsItemVisible()) // Skip rendering as ImDrawList elements are not clipped.
|
||||
continue;
|
||||
|
||||
const ImVec2 p0 = ImGui::GetItemRectMin();
|
||||
const ImVec2 p1 = ImGui::GetItemRectMax();
|
||||
const char* text_str = "Line 1 hello\nLine 2 clip me!";
|
||||
const ImVec2 text_pos = ImVec2(p0.x + offset.x, p0.y + offset.y);
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
switch (n)
|
||||
{
|
||||
case 0:
|
||||
HelpMarker(
|
||||
"Using ImGui::PushClipRect():\n"
|
||||
"Will alter ImGui hit-testing logic + ImDrawList rendering.\n"
|
||||
"(use this if you want your clipping rectangle to affect interactions)");
|
||||
ImGui::PushClipRect(p0, p1, true);
|
||||
draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255));
|
||||
draw_list->AddText(text_pos, IM_COL32_WHITE, text_str);
|
||||
ImGui::PopClipRect();
|
||||
break;
|
||||
case 1:
|
||||
HelpMarker(
|
||||
"Using ImDrawList::PushClipRect():\n"
|
||||
"Will alter ImDrawList rendering only.\n"
|
||||
"(use this as a shortcut if you are only using ImDrawList calls)");
|
||||
draw_list->PushClipRect(p0, p1, true);
|
||||
draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255));
|
||||
draw_list->AddText(text_pos, IM_COL32_WHITE, text_str);
|
||||
draw_list->PopClipRect();
|
||||
break;
|
||||
case 2:
|
||||
HelpMarker(
|
||||
"Using ImDrawList::AddText() with a fine ClipRect:\n"
|
||||
"Will alter only this specific ImDrawList::AddText() rendering.\n"
|
||||
"(this is often used internally to avoid altering the clipping rectangle and minimize draw calls)");
|
||||
ImVec4 clip_rect(p0.x, p0.y, p1.x, p1.y); // AddText() takes a ImVec4* here so let's convert.
|
||||
draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255));
|
||||
draw_list->AddText(ImGui::GetFont(), ImGui::GetFontSize(), text_pos, IM_COL32_WHITE, text_str, NULL, 0.0f, &clip_rect);
|
||||
break;
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::TreePop();
|
||||
@ -3620,19 +3619,12 @@ static void ShowDemoWindowPopups()
|
||||
ImGui::TextWrapped("Below we are testing adding menu items to a regular window. It's rather unusual but should work!");
|
||||
ImGui::Separator();
|
||||
|
||||
// Note: As a quirk in this very specific example, we want to differentiate the parent of this menu from the
|
||||
// parent of the various popup menus above. To do so we are encloding the items in a PushID()/PopID() block
|
||||
// to make them two different menusets. If we don't, opening any popup above and hovering our menu here would
|
||||
// open it. This is because once a menu is active, we allow to switch to a sibling menu by just hovering on it,
|
||||
// which is the desired behavior for regular menus.
|
||||
ImGui::PushID("foo");
|
||||
ImGui::MenuItem("Menu item", "CTRL+M");
|
||||
if (ImGui::BeginMenu("Menu inside a regular window"))
|
||||
{
|
||||
ShowExampleMenuFile();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::PopID();
|
||||
ImGui::Separator();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
@ -4914,7 +4906,7 @@ static void ShowDemoWindowTables()
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::SliderFloat("float1", &dummy_f, 0.0f, 1.0f);
|
||||
ImGui::TableSetColumnIndex(2);
|
||||
ImGui::SliderFloat("float2", &dummy_f, 0.0f, 1.0f);
|
||||
ImGui::SliderFloat("##float2", &dummy_f, 0.0f, 1.0f); // No visible label since right-aligned
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::EndTable();
|
||||
@ -5828,26 +5820,31 @@ static void ShowDemoWindowMisc()
|
||||
{ 2, 0, "", ImGuiKey_LeftShift },{ 2, 1, "Z", ImGuiKey_Z }, { 2, 2, "X", ImGuiKey_X }, { 2, 3, "C", ImGuiKey_C }, { 2, 4, "V", ImGuiKey_V }
|
||||
};
|
||||
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
draw_list->PushClipRect(board_min, board_max, true);
|
||||
for (int n = 0; n < IM_ARRAYSIZE(keys_to_display); n++)
|
||||
{
|
||||
const KeyLayoutData* key_data = &keys_to_display[n];
|
||||
ImVec2 key_min = ImVec2(start_pos.x + key_data->Col * key_step.x + key_data->Row * key_row_offset, start_pos.y + key_data->Row * key_step.y);
|
||||
ImVec2 key_max = ImVec2(key_min.x + key_size.x, key_min.y + key_size.y);
|
||||
draw_list->AddRectFilled(key_min, key_max, IM_COL32(204, 204, 204, 255), key_rounding);
|
||||
draw_list->AddRect(key_min, key_max, IM_COL32(24, 24, 24, 255), key_rounding);
|
||||
ImVec2 face_min = ImVec2(key_min.x + key_face_pos.x, key_min.y + key_face_pos.y);
|
||||
ImVec2 face_max = ImVec2(face_min.x + key_face_size.x, face_min.y + key_face_size.y);
|
||||
draw_list->AddRect(face_min, face_max, IM_COL32(193, 193, 193, 255), key_face_rounding, ImDrawFlags_None, 2.0f);
|
||||
draw_list->AddRectFilled(face_min, face_max, IM_COL32(252, 252, 252, 255), key_face_rounding);
|
||||
ImVec2 label_min = ImVec2(key_min.x + key_label_pos.x, key_min.y + key_label_pos.y);
|
||||
draw_list->AddText(label_min, IM_COL32(64, 64, 64, 255), key_data->Label);
|
||||
if (ImGui::IsKeyDown(key_data->Key))
|
||||
draw_list->AddRectFilled(key_min, key_max, IM_COL32(255, 0, 0, 128), key_rounding);
|
||||
}
|
||||
draw_list->PopClipRect();
|
||||
// Elements rendered manually via ImDrawList API are not clipped automatically.
|
||||
// While not strictly necessary, here IsItemVisible() is used to avoid rendering these shapes when they are out of view.
|
||||
ImGui::Dummy(ImVec2(board_max.x - board_min.x, board_max.y - board_min.y));
|
||||
if (ImGui::IsItemVisible())
|
||||
{
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
draw_list->PushClipRect(board_min, board_max, true);
|
||||
for (int n = 0; n < IM_ARRAYSIZE(keys_to_display); n++)
|
||||
{
|
||||
const KeyLayoutData* key_data = &keys_to_display[n];
|
||||
ImVec2 key_min = ImVec2(start_pos.x + key_data->Col * key_step.x + key_data->Row * key_row_offset, start_pos.y + key_data->Row * key_step.y);
|
||||
ImVec2 key_max = ImVec2(key_min.x + key_size.x, key_min.y + key_size.y);
|
||||
draw_list->AddRectFilled(key_min, key_max, IM_COL32(204, 204, 204, 255), key_rounding);
|
||||
draw_list->AddRect(key_min, key_max, IM_COL32(24, 24, 24, 255), key_rounding);
|
||||
ImVec2 face_min = ImVec2(key_min.x + key_face_pos.x, key_min.y + key_face_pos.y);
|
||||
ImVec2 face_max = ImVec2(face_min.x + key_face_size.x, face_min.y + key_face_size.y);
|
||||
draw_list->AddRect(face_min, face_max, IM_COL32(193, 193, 193, 255), key_face_rounding, ImDrawFlags_None, 2.0f);
|
||||
draw_list->AddRectFilled(face_min, face_max, IM_COL32(252, 252, 252, 255), key_face_rounding);
|
||||
ImVec2 label_min = ImVec2(key_min.x + key_label_pos.x, key_min.y + key_label_pos.y);
|
||||
draw_list->AddText(label_min, IM_COL32(64, 64, 64, 255), key_data->Label);
|
||||
if (ImGui::IsKeyDown(key_data->Key))
|
||||
draw_list->AddRectFilled(key_min, key_max, IM_COL32(255, 0, 0, 128), key_rounding);
|
||||
}
|
||||
draw_list->PopClipRect();
|
||||
}
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
@ -7455,7 +7452,7 @@ static void ShowExampleAppSimpleOverlay(bool* p_open)
|
||||
static void ShowExampleAppFullscreen(bool* p_open)
|
||||
{
|
||||
static bool use_work_area = true;
|
||||
static ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings;
|
||||
static ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings;
|
||||
|
||||
// We demonstrate using the full viewport area or the work area (without menu-bars, task-bars etc.)
|
||||
// Based on your use case you may want one of the other.
|
||||
|
@ -343,6 +343,8 @@ static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c =
|
||||
// Helpers: Formatting
|
||||
IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3);
|
||||
IMGUI_API int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) IM_FMTLIST(3);
|
||||
IMGUI_API void ImFormatStringToTempBuffer(const char** out_buf, const char** out_buf_end, const char* fmt, ...) IM_FMTARGS(3);
|
||||
IMGUI_API void ImFormatStringToTempBufferV(const char** out_buf, const char** out_buf_end, const char* fmt, va_list args) IM_FMTLIST(3);
|
||||
IMGUI_API const char* ImParseFormatFindStart(const char* format);
|
||||
IMGUI_API const char* ImParseFormatFindEnd(const char* format);
|
||||
IMGUI_API const char* ImParseFormatTrimDecorations(const char* format, char* buf, size_t buf_size);
|
||||
@ -1048,12 +1050,13 @@ struct ImGuiPopupData
|
||||
ImGuiID PopupId; // Set on OpenPopup()
|
||||
ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup()
|
||||
ImGuiWindow* SourceWindow; // Set on OpenPopup() copy of NavWindow at the time of opening the popup
|
||||
int ParentNavLayer; // Resolved on BeginPopup(). Actually a ImGuiNavLayer type (declared down below), initialized to -1 which is not part of an enum, but serves well-enough as "not any of layers" value
|
||||
int OpenFrameCount; // Set on OpenPopup()
|
||||
ImGuiID OpenParentId; // Set on OpenPopup(), we need this to differentiate multiple menu sets from each others (e.g. inside menu bar vs loose menu items)
|
||||
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() { memset(this, 0, sizeof(*this)); OpenFrameCount = -1; }
|
||||
ImGuiPopupData() { memset(this, 0, sizeof(*this)); ParentNavLayer = OpenFrameCount = -1; }
|
||||
};
|
||||
|
||||
enum ImGuiNextWindowDataFlags_
|
||||
@ -2002,7 +2005,7 @@ struct ImGuiContext
|
||||
int WantCaptureMouseNextFrame; // Explicit capture override via SetNextFrameWantCaptureMouse()/SetNextFrameWantCaptureKeyboard(). Default to -1.
|
||||
int WantCaptureKeyboardNextFrame; // "
|
||||
int WantTextInputNextFrame;
|
||||
char TempBuffer[1024 * 3 + 1]; // Temporary text buffer
|
||||
ImVector<char> TempBuffer; // Temporary text buffer
|
||||
|
||||
ImGuiContext(ImFontAtlas* shared_font_atlas)
|
||||
{
|
||||
@ -2160,7 +2163,6 @@ struct ImGuiContext
|
||||
FramerateSecPerFrameIdx = FramerateSecPerFrameCount = 0;
|
||||
FramerateSecPerFrameAccum = 0.0f;
|
||||
WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1;
|
||||
memset(TempBuffer, 0, sizeof(TempBuffer));
|
||||
}
|
||||
};
|
||||
|
||||
@ -3169,6 +3171,7 @@ namespace ImGui
|
||||
IMGUI_API void DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label);
|
||||
IMGUI_API void DebugNodeTable(ImGuiTable* table);
|
||||
IMGUI_API void DebugNodeTableSettings(ImGuiTableSettings* settings);
|
||||
IMGUI_API void DebugNodeInputTextState(ImGuiInputTextState* state);
|
||||
IMGUI_API void DebugNodeWindow(ImGuiWindow* window, const char* label);
|
||||
IMGUI_API void DebugNodeWindowSettings(ImGuiWindowSettings* settings);
|
||||
IMGUI_API void DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* label);
|
||||
|
@ -2370,7 +2370,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
||||
|
||||
// Don't attempt to merge if there are multiple draw calls within the column
|
||||
ImDrawChannel* src_channel = &splitter->_Channels[channel_no];
|
||||
if (src_channel->_CmdBuffer.Size > 0 && src_channel->_CmdBuffer.back().ElemCount == 0 && src_channel->_CmdBuffer.back().UserCallback != NULL) // Equivalent of PopUnusedDrawCmd()
|
||||
if (src_channel->_CmdBuffer.Size > 0 && src_channel->_CmdBuffer.back().ElemCount == 0 && src_channel->_CmdBuffer.back().UserCallback == NULL) // Equivalent of PopUnusedDrawCmd()
|
||||
src_channel->_CmdBuffer.pop_back();
|
||||
if (src_channel->_CmdBuffer.Size != 1)
|
||||
continue;
|
||||
|
@ -276,9 +276,9 @@ void ImGui::TextV(const char* fmt, va_list args)
|
||||
return;
|
||||
|
||||
// FIXME-OPT: Handle the %s shortcut?
|
||||
ImGuiContext& g = *GImGui;
|
||||
const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
||||
TextEx(g.TempBuffer, text_end, ImGuiTextFlags_NoWidthForLargeClippedText);
|
||||
const char* text, *text_end;
|
||||
ImFormatStringToTempBufferV(&text, &text_end, fmt, args);
|
||||
TextEx(text, text_end, ImGuiTextFlags_NoWidthForLargeClippedText);
|
||||
}
|
||||
|
||||
void ImGui::TextColored(const ImVec4& col, const char* fmt, ...)
|
||||
@ -359,8 +359,8 @@ void ImGui::LabelTextV(const char* label, const char* fmt, va_list args)
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const float w = CalcItemWidth();
|
||||
|
||||
const char* value_text_begin = &g.TempBuffer[0];
|
||||
const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
||||
const char* value_text_begin, *value_text_end;
|
||||
ImFormatStringToTempBufferV(&value_text_begin, &value_text_end, fmt, args);
|
||||
const ImVec2 value_size = CalcTextSize(value_text_begin, value_text_end, false);
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
|
||||
@ -395,8 +395,8 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
|
||||
const char* text_begin = g.TempBuffer;
|
||||
const char* text_end = text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
||||
const char* text_begin, *text_end;
|
||||
ImFormatStringToTempBufferV(&text_begin, &text_end, fmt, args);
|
||||
const ImVec2 label_size = CalcTextSize(text_begin, text_end, false);
|
||||
const ImVec2 total_size = ImVec2(g.FontSize + (label_size.x > 0.0f ? (label_size.x + style.FramePadding.x * 2) : 0.0f), label_size.y); // Empty text doesn't add padding
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
@ -1918,9 +1918,9 @@ static const char* PatchFormatStringFloatToInt(const char* fmt)
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
if (fmt_start == fmt && fmt_end[0] == 0)
|
||||
return "%d";
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%.*s%%d%s", (int)(fmt_start - fmt), fmt, fmt_end); // Honor leading and trailing decorations, but lose alignment/precision.
|
||||
return g.TempBuffer;
|
||||
const char* tmp_format;
|
||||
ImFormatStringToTempBuffer(&tmp_format, NULL, "%.*s%%d%s", (int)(fmt_start - fmt), fmt, fmt_end); // Honor leading and trailing decorations, but lose alignment/precision.
|
||||
return tmp_format;
|
||||
#else
|
||||
IM_ASSERT(0 && "DragInt(): Invalid format string!"); // Old versions used a default parameter of "%.0f", please replace with e.g. "%d"
|
||||
#endif
|
||||
@ -3579,6 +3579,7 @@ bool ImGui::InputDouble(const char* label, double* v, double step, double step_f
|
||||
// - InputTextReindexLines() [Internal]
|
||||
// - InputTextReindexLinesRange() [Internal]
|
||||
// - InputTextEx() [Internal]
|
||||
// - DebugNodeInputTextState() [Internal]
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
|
||||
@ -3936,6 +3937,41 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find the shortest single replacement we can make to get the new text from the old text.
|
||||
// Important: needs to be run before TextW is rewritten with the new characters because calling STB_TEXTEDIT_GETCHAR() at the end.
|
||||
// FIXME: Ideally we should transition toward (1) making InsertChars()/DeleteChars() update undo-stack (2) discourage (and keep reconcile) or obsolete (and remove reconcile) accessing buffer directly.
|
||||
static void InputTextReconcileUndoStateAfterUserCallback(ImGuiInputTextState* state, const char* new_buf_a, int new_length_a)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImWchar* old_buf = state->TextW.Data;
|
||||
const int old_length = state->CurLenW;
|
||||
const int new_length = ImTextCountCharsFromUtf8(new_buf_a, new_buf_a + new_length_a);
|
||||
g.TempBuffer.reserve_discard((new_length + 1) * sizeof(ImWchar));
|
||||
ImWchar* new_buf = (ImWchar*)(void*)g.TempBuffer.Data;
|
||||
ImTextStrFromUtf8(new_buf, new_length + 1, new_buf_a, new_buf_a + new_length_a);
|
||||
|
||||
const int shorter_length = ImMin(old_length, new_length);
|
||||
int first_diff;
|
||||
for (first_diff = 0; first_diff < shorter_length; first_diff++)
|
||||
if (old_buf[first_diff] != new_buf[first_diff])
|
||||
break;
|
||||
if (first_diff == old_length && first_diff == new_length)
|
||||
return;
|
||||
|
||||
int old_last_diff = old_length - 1;
|
||||
int new_last_diff = new_length - 1;
|
||||
for (; old_last_diff >= first_diff && new_last_diff >= first_diff; old_last_diff--, new_last_diff--)
|
||||
if (old_buf[old_last_diff] != new_buf[new_last_diff])
|
||||
break;
|
||||
|
||||
const int insert_len = new_last_diff - first_diff + 1;
|
||||
const int delete_len = old_last_diff - first_diff + 1;
|
||||
if (insert_len > 0 || delete_len > 0)
|
||||
if (STB_TEXTEDIT_CHARTYPE* p = stb_text_createundo(&state->Stb.undostate, first_diff, delete_len, insert_len))
|
||||
for (int i = 0; i < delete_len; i++)
|
||||
p[i] = ImStb::STB_TEXTEDIT_GETCHAR(state, first_diff + i);
|
||||
}
|
||||
|
||||
// Edit a string of text
|
||||
// - buf_size account for the zero-terminator, so a buf_size of 6 can hold "Hello" but not "Hello!".
|
||||
// This is so we can easily call InputText() on static arrays using ARRAYSIZE() and to match
|
||||
@ -4056,17 +4092,21 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
state->InitialTextA.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||
memcpy(state->InitialTextA.Data, buf, buf_len + 1);
|
||||
|
||||
// Preserve cursor position and undo/redo stack if we come back to same widget
|
||||
// FIXME: Since we reworked this on 2022/06, may want to differenciate recycle_cursor vs recycle_undostate?
|
||||
bool recycle_state = (state->ID == id && !init_changed_specs);
|
||||
if (recycle_state && (state->CurLenA != buf_len || (state->TextAIsValid && strncmp(state->TextA.Data, buf, buf_len) != 0)))
|
||||
recycle_state = false;
|
||||
|
||||
// Start edition
|
||||
const char* buf_end = NULL;
|
||||
state->ID = id;
|
||||
state->TextW.resize(buf_size + 1); // wchar count <= UTF-8 count. we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||
state->TextA.resize(0);
|
||||
state->TextAIsValid = false; // TextA is not valid yet (we will display buf until then)
|
||||
state->CurLenW = ImTextStrFromUtf8(state->TextW.Data, buf_size, buf, NULL, &buf_end);
|
||||
state->CurLenA = (int)(buf_end - buf); // We can't get the result from ImStrncpy() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8.
|
||||
|
||||
// Preserve cursor position and undo/redo stack if we come back to same widget
|
||||
// FIXME: For non-readonly widgets we might be able to require that TextAIsValid && TextA == buf ? (untested) and discard undo stack if user buffer has changed.
|
||||
const bool recycle_state = (state->ID == id && !init_changed_specs);
|
||||
if (recycle_state)
|
||||
{
|
||||
// Recycle existing cursor/selection/undo stack but clamp position
|
||||
@ -4075,7 +4115,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
}
|
||||
else
|
||||
{
|
||||
state->ID = id;
|
||||
state->ScrollX = 0.0f;
|
||||
stb_textedit_initialize_state(&state->Stb, !is_multiline);
|
||||
}
|
||||
@ -4520,8 +4559,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (buf_dirty)
|
||||
{
|
||||
IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
|
||||
InputTextReconcileUndoStateAfterUserCallback(state, callback_data.Buf, callback_data.BufTextLen); // FIXME: Move the rest of this block inside function and rename to InputTextReconcileStateAfterUserCallback() ?
|
||||
if (callback_data.BufTextLen > backup_current_text_length && is_resizable)
|
||||
state->TextW.resize(state->TextW.Size + (callback_data.BufTextLen - backup_current_text_length));
|
||||
state->TextW.resize(state->TextW.Size + (callback_data.BufTextLen - backup_current_text_length)); // Worse case scenario resize
|
||||
state->CurLenW = ImTextStrFromUtf8(state->TextW.Data, state->TextW.Size, callback_data.Buf, NULL);
|
||||
state->CurLenA = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen()
|
||||
state->CursorAnimReset();
|
||||
@ -4825,6 +4865,40 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
void ImGui::DebugNodeInputTextState(ImGuiInputTextState* state)
|
||||
{
|
||||
#ifndef IMGUI_DISABLE_METRICS_WINDOW
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImStb::STB_TexteditState* stb_state = &state->Stb;
|
||||
ImStb::StbUndoState* undo_state = &stb_state->undostate;
|
||||
Text("ID: 0x%08X, ActiveID: 0x%08X", state->ID, g.ActiveId);
|
||||
Text("CurLenW: %d, CurLenA: %d, Cursor: %d, Selection: %d..%d", state->CurLenA, state->CurLenW, stb_state->cursor, stb_state->select_start, stb_state->select_end);
|
||||
Text("undo_point: %d, redo_point: %d, undo_char_point: %d, redo_char_point: %d", undo_state->undo_point, undo_state->redo_point, undo_state->undo_char_point, undo_state->redo_char_point);
|
||||
if (BeginChild("undopoints", ImVec2(0.0f, GetTextLineHeight() * 15), true)) // Visualize undo state
|
||||
{
|
||||
PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
||||
for (int n = 0; n < STB_TEXTEDIT_UNDOSTATECOUNT; n++)
|
||||
{
|
||||
ImStb::StbUndoRecord* undo_rec = &undo_state->undo_rec[n];
|
||||
const char undo_rec_type = (n < undo_state->undo_point) ? 'u' : (n >= undo_state->redo_point) ? 'r' : ' ';
|
||||
if (undo_rec_type == ' ')
|
||||
BeginDisabled();
|
||||
char buf[64] = "";
|
||||
if (undo_rec_type != ' ' && undo_rec->char_storage != -1)
|
||||
ImTextStrToUtf8(buf, IM_ARRAYSIZE(buf), undo_state->undo_char + undo_rec->char_storage, undo_state->undo_char + undo_rec->char_storage + undo_rec->insert_length);
|
||||
Text("%c [%02d] where %03d, insert %03d, delete %03d, char_storage %03d \"%s\"",
|
||||
undo_rec_type, n, undo_rec->where, undo_rec->insert_length, undo_rec->delete_length, undo_rec->char_storage, buf);
|
||||
if (undo_rec_type == ' ')
|
||||
EndDisabled();
|
||||
}
|
||||
PopStyleVar();
|
||||
}
|
||||
EndChild();
|
||||
#else
|
||||
IM_UNUSED(state);
|
||||
#endif
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] Widgets: ColorEdit, ColorPicker, ColorButton, etc.
|
||||
//-------------------------------------------------------------------------
|
||||
@ -5806,9 +5880,9 @@ bool ImGui::TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
||||
return TreeNodeBehavior(window->GetID(str_id), flags, g.TempBuffer, label_end);
|
||||
const char* label, *label_end;
|
||||
ImFormatStringToTempBufferV(&label, &label_end, fmt, args);
|
||||
return TreeNodeBehavior(window->GetID(str_id), flags, label, label_end);
|
||||
}
|
||||
|
||||
bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args)
|
||||
@ -5817,9 +5891,9 @@ bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
||||
return TreeNodeBehavior(window->GetID(ptr_id), flags, g.TempBuffer, label_end);
|
||||
const char* label, *label_end;
|
||||
ImFormatStringToTempBufferV(&label, &label_end, fmt, args);
|
||||
return TreeNodeBehavior(window->GetID(ptr_id), flags, label, label_end);
|
||||
}
|
||||
|
||||
bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags)
|
||||
@ -6878,14 +6952,19 @@ static bool IsRootOfOpenMenuSet()
|
||||
if ((g.OpenPopupStack.Size <= g.BeginPopupStack.Size) || (window->Flags & ImGuiWindowFlags_ChildMenu))
|
||||
return false;
|
||||
|
||||
// Initially we used 'OpenParentId' to differentiate multiple menu sets from each others (e.g. inside menu bar vs loose menu items) based on parent ID.
|
||||
// Initially we used 'upper_popup->OpenParentId == window->IDStack.back()' to differentiate multiple menu sets from each others
|
||||
// (e.g. inside menu bar vs loose menu items) based on parent ID.
|
||||
// This would however prevent the use of e.g. PuhsID() user code submitting menus.
|
||||
// Previously this worked between popup and a first child menu because the first child menu always had the _ChildWindow flag,
|
||||
// making hovering on parent popup possible while first child menu was focused - but this was generally a bug with other side effects.
|
||||
// Instead we don't treat Popup specifically (in order to consistently support menu features in them), maybe the first child menu of a Popup
|
||||
// doesn't have the _ChildWindow flag, and we rely on this IsRootOfOpenMenuSet() check to allow hovering between root window/popup and first chilld menu.
|
||||
// doesn't have the _ChildWindow flag, and we rely on this IsRootOfOpenMenuSet() check to allow hovering between root window/popup and first child menu.
|
||||
// In the end, lack of ID check made it so we could no longer differentiate between separate menu sets. To compensate for that, we at least check parent window nav layer.
|
||||
// This fixes the most common case of menu opening on hover when moving between window content and menu bar. Multiple different menu sets in same nav layer would still
|
||||
// open on hover, but that should be a lesser problem, because if such menus are close in proximity in window content then it won't feel weird and if they are far apart
|
||||
// it likely won't be a problem anyone runs into.
|
||||
const ImGuiPopupData* upper_popup = &g.OpenPopupStack[g.BeginPopupStack.Size];
|
||||
return (/*upper_popup->OpenParentId == window->IDStack.back() &&*/ upper_popup->Window && (upper_popup->Window->Flags & ImGuiWindowFlags_ChildMenu));
|
||||
return (window->DC.NavLayerCurrent == upper_popup->ParentNavLayer && upper_popup->Window && (upper_popup->Window->Flags & ImGuiWindowFlags_ChildMenu));
|
||||
}
|
||||
|
||||
bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
@ -6900,7 +6979,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
bool menu_is_open = IsPopupOpen(id, ImGuiPopupFlags_None);
|
||||
|
||||
// Sub-menus are ChildWindow so that mouse can be hovering across them (otherwise top-most popup menu would steal focus and not allow hovering on parent menu)
|
||||
// The first menu in a hierarchy isn't so hovering doesn't get accross (otherwise e.g. resizing borders with ImGuiButtonFlags_FlattenChildren would react), but top-most BeginMenu() will bypass that limitation.
|
||||
// The first menu in a hierarchy isn't so hovering doesn't get across (otherwise e.g. resizing borders with ImGuiButtonFlags_FlattenChildren would react), but top-most BeginMenu() will bypass that limitation.
|
||||
ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus;
|
||||
if (window->Flags & ImGuiWindowFlags_ChildMenu)
|
||||
flags |= ImGuiWindowFlags_ChildWindow;
|
||||
|
@ -66,7 +66,7 @@ int main(int argc, char** argv)
|
||||
char Encode85Byte(unsigned int x)
|
||||
{
|
||||
x = (x % 85) + 35;
|
||||
return (x >= '\\') ? x + 1 : x;
|
||||
return (char)((x >= '\\') ? x + 1 : x);
|
||||
}
|
||||
|
||||
bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression, bool use_static)
|
||||
@ -263,17 +263,17 @@ static int stb_compress_chunk(stb_uchar *history,
|
||||
int best = 2, dist=0;
|
||||
|
||||
if (q+65536 > end)
|
||||
match_max = end-q;
|
||||
match_max = (stb_uint)(end-q);
|
||||
else
|
||||
match_max = 65536;
|
||||
|
||||
#define stb__nc(b,d) ((d) <= window && ((b) > 9 || stb_not_crap(b,d)))
|
||||
#define stb__nc(b,d) ((d) <= window && ((b) > 9 || stb_not_crap((int)(b),(int)(d))))
|
||||
|
||||
#define STB__TRY(t,p) /* avoid retrying a match we already tried */ \
|
||||
if (p ? dist != q-t : 1) \
|
||||
if (p ? dist != (int)(q-t) : 1) \
|
||||
if ((m = stb_matchlen(t, q, match_max)) > best) \
|
||||
if (stb__nc(m,q-(t))) \
|
||||
best = m, dist = q - (t)
|
||||
best = m, dist = (int)(q - (t))
|
||||
|
||||
// rather than search for all matches, only try 4 candidate locations,
|
||||
// chosen based on 4 different hash functions of different lengths.
|
||||
@ -299,24 +299,24 @@ static int stb_compress_chunk(stb_uchar *history,
|
||||
if (best < 3) { // fast path literals
|
||||
++q;
|
||||
} else if (best > 2 && best <= 0x80 && dist <= 0x100) {
|
||||
outliterals(lit_start, q-lit_start); lit_start = (q += best);
|
||||
outliterals(lit_start, (int)(q-lit_start)); lit_start = (q += best);
|
||||
stb_out(0x80 + best-1);
|
||||
stb_out(dist-1);
|
||||
} else if (best > 5 && best <= 0x100 && dist <= 0x4000) {
|
||||
outliterals(lit_start, q-lit_start); lit_start = (q += best);
|
||||
outliterals(lit_start, (int)(q-lit_start)); lit_start = (q += best);
|
||||
stb_out2(0x4000 + dist-1);
|
||||
stb_out(best-1);
|
||||
} else if (best > 7 && best <= 0x100 && dist <= 0x80000) {
|
||||
outliterals(lit_start, q-lit_start); lit_start = (q += best);
|
||||
outliterals(lit_start, (int)(q-lit_start)); lit_start = (q += best);
|
||||
stb_out3(0x180000 + dist-1);
|
||||
stb_out(best-1);
|
||||
} else if (best > 8 && best <= 0x10000 && dist <= 0x80000) {
|
||||
outliterals(lit_start, q-lit_start); lit_start = (q += best);
|
||||
outliterals(lit_start, (int)(q-lit_start)); lit_start = (q += best);
|
||||
stb_out3(0x100000 + dist-1);
|
||||
stb_out2(best-1);
|
||||
} else if (best > 9 && dist <= 0x1000000) {
|
||||
if (best > 65536) best = 65536;
|
||||
outliterals(lit_start, q-lit_start); lit_start = (q += best);
|
||||
outliterals(lit_start, (int)(q-lit_start)); lit_start = (q += best);
|
||||
if (best <= 0x100) {
|
||||
stb_out(0x06);
|
||||
stb_out3(dist-1);
|
||||
@ -336,10 +336,10 @@ static int stb_compress_chunk(stb_uchar *history,
|
||||
q = start+length;
|
||||
|
||||
// the literals are everything from lit_start to q
|
||||
*pending_literals = (q - lit_start);
|
||||
*pending_literals = (int)(q - lit_start);
|
||||
|
||||
stb__running_adler = stb_adler32(stb__running_adler, start, q - start);
|
||||
return q - start;
|
||||
stb__running_adler = stb_adler32(stb__running_adler, start, (stb_uint)(q - start));
|
||||
return (int)(q - start);
|
||||
}
|
||||
|
||||
static int stb_compress_inner(stb_uchar *input, stb_uint length)
|
||||
@ -384,5 +384,5 @@ stb_uint stb_compress(stb_uchar *out, stb_uchar *input, stb_uint length)
|
||||
|
||||
stb_compress_inner(input, length);
|
||||
|
||||
return stb__out - out;
|
||||
return (stb_uint)(stb__out - out);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user