Merge branch 'viewport' into docking

# Conflicts:
#	imgui.cpp
This commit is contained in:
omar
2019-01-10 16:02:32 +01:00
9 changed files with 238 additions and 169 deletions

View File

@ -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;