mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-04 12:08:47 +02:00
Merge branch 'viewport' into docking
# Conflicts: # imgui.cpp
This commit is contained in:
98
imgui.cpp
98
imgui.cpp
@ -1296,11 +1296,25 @@ void ImStrncpy(char* dst, const char* src, size_t count)
|
||||
dst[count-1] = 0;
|
||||
}
|
||||
|
||||
char* ImStrdup(const char *str)
|
||||
char* ImStrdup(const char* str)
|
||||
{
|
||||
size_t len = strlen(str) + 1;
|
||||
void* buf = ImGui::MemAlloc(len);
|
||||
return (char*)memcpy(buf, (const void*)str, len);
|
||||
size_t len = strlen(str);
|
||||
void* buf = ImGui::MemAlloc(len + 1);
|
||||
return (char*)memcpy(buf, (const void*)str, len + 1);
|
||||
}
|
||||
|
||||
char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* src)
|
||||
{
|
||||
size_t dst_buf_size = p_dst_size ? *p_dst_size : strlen(dst) + 1;
|
||||
size_t src_size = strlen(src) + 1;
|
||||
if (dst_buf_size < src_size)
|
||||
{
|
||||
ImGui::MemFree(dst);
|
||||
dst = (char*)ImGui::MemAlloc(src_size);
|
||||
if (p_dst_size)
|
||||
*p_dst_size = src_size;
|
||||
}
|
||||
return (char*)memcpy(dst, (const void*)src, src_size);
|
||||
}
|
||||
|
||||
const char* ImStrchrRange(const char* str, const char* str_end, char c)
|
||||
@ -1381,6 +1395,12 @@ const char* ImStrSkipBlank(const char* str)
|
||||
// B) When buf==NULL vsnprintf() will return the output size.
|
||||
#ifndef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS
|
||||
|
||||
//#define IMGUI_USE_STB_SPRINTF
|
||||
#ifdef IMGUI_USE_STB_SPRINTF
|
||||
#define STB_SPRINTF_IMPLEMENTATION
|
||||
#include "imstb_sprintf.h"
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(vsnprintf)
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
@ -1389,7 +1409,11 @@ int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
#ifdef IMGUI_USE_STB_SPRINTF
|
||||
int w = stbsp_vsnprintf(buf, (int)buf_size, fmt, args);
|
||||
#else
|
||||
int w = vsnprintf(buf, buf_size, fmt, args);
|
||||
#endif
|
||||
va_end(args);
|
||||
if (buf == NULL)
|
||||
return w;
|
||||
@ -1401,7 +1425,11 @@ int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...)
|
||||
|
||||
int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args)
|
||||
{
|
||||
#ifdef IMGUI_USE_STB_SPRINTF
|
||||
int w = stbsp_vsnprintf(buf, (int)buf_size, fmt, args);
|
||||
#else
|
||||
int w = vsnprintf(buf, buf_size, fmt, args);
|
||||
#endif
|
||||
if (buf == NULL)
|
||||
return w;
|
||||
if (w == -1 || w >= (int)buf_size)
|
||||
@ -1411,7 +1439,9 @@ int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args)
|
||||
}
|
||||
#endif // #ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS
|
||||
|
||||
// Pass data_size==0 for zero-terminated strings
|
||||
// Pass data_size == 0 for zero-terminated strings, data_size > 0 for non-string data.
|
||||
// Pay attention that data_size==0 will yield different results than passing strlen(data) because the zero-terminated codepath handles ###.
|
||||
// This should technically be split into two distinct functions (ImHashData/ImHashStr), perhaps once we remove the silly static variable.
|
||||
// FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements.
|
||||
ImU32 ImHash(const void* data, int data_size, ImU32 seed)
|
||||
{
|
||||
@ -1810,15 +1840,15 @@ ImU32 ImGui::GetColorU32(ImU32 col)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// std::lower_bound but without the bullshit
|
||||
static ImVector<ImGuiStorage::Pair>::iterator LowerBound(ImVector<ImGuiStorage::Pair>& data, ImGuiID key)
|
||||
static ImGuiStorage::Pair* LowerBound(ImVector<ImGuiStorage::Pair>& data, ImGuiID key)
|
||||
{
|
||||
ImVector<ImGuiStorage::Pair>::iterator first = data.begin();
|
||||
ImVector<ImGuiStorage::Pair>::iterator last = data.end();
|
||||
ImGuiStorage::Pair* first = data.Data;
|
||||
ImGuiStorage::Pair* last = data.Data + data.Size;
|
||||
size_t count = (size_t)(last - first);
|
||||
while (count > 0)
|
||||
{
|
||||
size_t count2 = count >> 1;
|
||||
ImVector<ImGuiStorage::Pair>::iterator mid = first + count2;
|
||||
ImGuiStorage::Pair* mid = first + count2;
|
||||
if (mid->key < key)
|
||||
{
|
||||
first = ++mid;
|
||||
@ -1851,7 +1881,7 @@ void ImGuiStorage::BuildSortByKey()
|
||||
|
||||
int ImGuiStorage::GetInt(ImGuiID key, int default_val) const
|
||||
{
|
||||
ImVector<Pair>::iterator it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key);
|
||||
ImGuiStorage::Pair* it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key);
|
||||
if (it == Data.end() || it->key != key)
|
||||
return default_val;
|
||||
return it->val_i;
|
||||
@ -1864,7 +1894,7 @@ bool ImGuiStorage::GetBool(ImGuiID key, bool default_val) const
|
||||
|
||||
float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const
|
||||
{
|
||||
ImVector<Pair>::iterator it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key);
|
||||
ImGuiStorage::Pair* it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key);
|
||||
if (it == Data.end() || it->key != key)
|
||||
return default_val;
|
||||
return it->val_f;
|
||||
@ -1872,7 +1902,7 @@ float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const
|
||||
|
||||
void* ImGuiStorage::GetVoidPtr(ImGuiID key) const
|
||||
{
|
||||
ImVector<Pair>::iterator it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key);
|
||||
ImGuiStorage::Pair* it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key);
|
||||
if (it == Data.end() || it->key != key)
|
||||
return NULL;
|
||||
return it->val_p;
|
||||
@ -1881,7 +1911,7 @@ void* ImGuiStorage::GetVoidPtr(ImGuiID key) const
|
||||
// References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer.
|
||||
int* ImGuiStorage::GetIntRef(ImGuiID key, int default_val)
|
||||
{
|
||||
ImVector<Pair>::iterator it = LowerBound(Data, key);
|
||||
ImGuiStorage::Pair* it = LowerBound(Data, key);
|
||||
if (it == Data.end() || it->key != key)
|
||||
it = Data.insert(it, Pair(key, default_val));
|
||||
return &it->val_i;
|
||||
@ -1894,7 +1924,7 @@ bool* ImGuiStorage::GetBoolRef(ImGuiID key, bool default_val)
|
||||
|
||||
float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val)
|
||||
{
|
||||
ImVector<Pair>::iterator it = LowerBound(Data, key);
|
||||
ImGuiStorage::Pair* it = LowerBound(Data, key);
|
||||
if (it == Data.end() || it->key != key)
|
||||
it = Data.insert(it, Pair(key, default_val));
|
||||
return &it->val_f;
|
||||
@ -1902,7 +1932,7 @@ float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val)
|
||||
|
||||
void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val)
|
||||
{
|
||||
ImVector<Pair>::iterator it = LowerBound(Data, key);
|
||||
ImGuiStorage::Pair* it = LowerBound(Data, key);
|
||||
if (it == Data.end() || it->key != key)
|
||||
it = Data.insert(it, Pair(key, default_val));
|
||||
return &it->val_p;
|
||||
@ -1911,7 +1941,7 @@ void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val)
|
||||
// FIXME-OPT: Need a way to reuse the result of lower_bound when doing GetInt()/SetInt() - not too bad because it only happens on explicit interaction (maximum one a frame)
|
||||
void ImGuiStorage::SetInt(ImGuiID key, int val)
|
||||
{
|
||||
ImVector<Pair>::iterator it = LowerBound(Data, key);
|
||||
ImGuiStorage::Pair* it = LowerBound(Data, key);
|
||||
if (it == Data.end() || it->key != key)
|
||||
{
|
||||
Data.insert(it, Pair(key, val));
|
||||
@ -1927,7 +1957,7 @@ void ImGuiStorage::SetBool(ImGuiID key, bool val)
|
||||
|
||||
void ImGuiStorage::SetFloat(ImGuiID key, float val)
|
||||
{
|
||||
ImVector<Pair>::iterator it = LowerBound(Data, key);
|
||||
ImGuiStorage::Pair* it = LowerBound(Data, key);
|
||||
if (it == Data.end() || it->key != key)
|
||||
{
|
||||
Data.insert(it, Pair(key, val));
|
||||
@ -1938,7 +1968,7 @@ void ImGuiStorage::SetFloat(ImGuiID key, float val)
|
||||
|
||||
void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val)
|
||||
{
|
||||
ImVector<Pair>::iterator it = LowerBound(Data, key);
|
||||
ImGuiStorage::Pair* it = LowerBound(Data, key);
|
||||
if (it == Data.end() || it->key != key)
|
||||
{
|
||||
Data.insert(it, Pair(key, val));
|
||||
@ -2439,6 +2469,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
|
||||
WindowPadding = ImVec2(0.0f, 0.0f);
|
||||
WindowRounding = 0.0f;
|
||||
WindowBorderSize = 0.0f;
|
||||
NameBufLen = (int)strlen(name) + 1;
|
||||
MoveId = GetID("#MOVE");
|
||||
ChildId = 0;
|
||||
Scroll = ImVec2(0.0f, 0.0f);
|
||||
@ -2695,7 +2726,8 @@ void ImGui::ItemSize(const ImVec2& size, float text_offset_y)
|
||||
const float text_base_offset = ImMax(window->DC.CurrentLineTextBaseOffset, text_offset_y);
|
||||
//if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG]
|
||||
window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y);
|
||||
window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y));
|
||||
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
window->DC.CursorPos.y = (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y);
|
||||
window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x);
|
||||
window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y - g.Style.ItemSpacing.y);
|
||||
//if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG]
|
||||
@ -2741,7 +2773,8 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg)
|
||||
window->DC.LastItemStatusFlags = ImGuiItemStatusFlags_None;
|
||||
|
||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||
ImGuiTestEngineHook_ItemAdd(bb, id);
|
||||
if (id != 0)
|
||||
ImGuiTestEngineHook_ItemAdd(&g, bb, id);
|
||||
#endif
|
||||
|
||||
// Clipping test
|
||||
@ -3357,7 +3390,7 @@ void ImGui::NewFrame()
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||
ImGuiTestEngineHook_PreNewFrame();
|
||||
ImGuiTestEngineHook_PreNewFrame(&g);
|
||||
#endif
|
||||
|
||||
// Check user data
|
||||
@ -3587,7 +3620,7 @@ void ImGui::NewFrame()
|
||||
g.FrameScopePushedImplicitWindow = true;
|
||||
|
||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||
ImGuiTestEngineHook_PostNewFrame();
|
||||
ImGuiTestEngineHook_PostNewFrame(&g);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -4650,7 +4683,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
|
||||
if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID))
|
||||
{
|
||||
// Retrieve settings from .ini file
|
||||
window->SettingsIdx = g.SettingsWindows.index_from_pointer(settings);
|
||||
window->SettingsIdx = g.SettingsWindows.index_from_ptr(settings);
|
||||
SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false);
|
||||
if (settings->ViewportId)
|
||||
{
|
||||
@ -5166,13 +5199,18 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX);
|
||||
window->IDStack.resize(1);
|
||||
|
||||
// Update stored window name when it changes (which can only happen with the "###" operator).
|
||||
// The title bar always display the 'name' parameter, so we only update storage if the title is displayed to the end-user in a different place.
|
||||
bool window_title_visible_elsewhere = (window->Viewport && window->Viewport->Window == window) || (window->DockIsActive);
|
||||
if (!window_just_created && window_title_visible_elsewhere && strcmp(name, window->Name) != 0)
|
||||
// Update stored window name when it changes (which can _only_ happen with the "###" operator, so the ID would stay unchanged).
|
||||
// The title bar always display the 'name' parameter, so we only update the string storage if it needs to be visible to the end-user elsewhere.
|
||||
bool window_title_visible_elsewhere = false;
|
||||
if ((window->Viewport && window->Viewport->Window == window) || (window->DockIsActive))
|
||||
window_title_visible_elsewhere = true;
|
||||
else if (g.NavWindowingList != NULL && (window->Flags & ImGuiWindowFlags_NoNavFocus) == 0) // Window titles visible when using CTRL+TAB
|
||||
window_title_visible_elsewhere = true;
|
||||
if (window_title_visible_elsewhere && !window_just_created && strcmp(name, window->Name) != 0)
|
||||
{
|
||||
IM_DELETE(window->Name);
|
||||
window->Name = ImStrdup(name);
|
||||
size_t buf_len = (size_t)window->NameBufLen;
|
||||
window->Name = ImStrdupcpy(window->Name, &buf_len, name);
|
||||
window->NameBufLen = (int)buf_len;
|
||||
}
|
||||
|
||||
// UPDATE CONTENTS SIZE, UPDATE HIDDEN STATUS
|
||||
@ -13254,7 +13292,7 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSetting
|
||||
if (!settings)
|
||||
{
|
||||
settings = ImGui::CreateNewWindowSettings(window->Name);
|
||||
window->SettingsIdx = g.SettingsWindows.index_from_pointer(settings);
|
||||
window->SettingsIdx = g.SettingsWindows.index_from_ptr(settings);
|
||||
}
|
||||
IM_ASSERT(settings->ID == window->ID);
|
||||
settings->Pos = window->Pos - window->ViewportPos;
|
||||
|
Reference in New Issue
Block a user