1
0
mirror of https://github.com/ocornut/imgui.git synced 2024-11-28 09:30:56 +01:00

Merge branch 'master' into drag_and_drop

This commit is contained in:
omar 2017-11-16 13:28:22 +01:00
commit 7746dd104c
4 changed files with 86 additions and 57 deletions

View File

@ -1376,13 +1376,8 @@ void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int*
//-----------------------------------------------------------------------------
// ImGuiStorage
//-----------------------------------------------------------------------------
// Helper: Key->value storage
void ImGuiStorage::Clear()
{
Data.clear();
}
//-----------------------------------------------------------------------------
// std::lower_bound but without the bullshit
static ImVector<ImGuiStorage::Pair>::iterator LowerBound(ImVector<ImGuiStorage::Pair>& data, ImGuiID key)
@ -1652,7 +1647,7 @@ void ImGuiTextBuffer::append(const char* fmt, ...)
}
//-----------------------------------------------------------------------------
// ImGuiSimpleColumns
// ImGuiSimpleColumns (internal use only)
//-----------------------------------------------------------------------------
ImGuiSimpleColumns::ImGuiSimpleColumns()
@ -1806,6 +1801,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
Collapsed = false;
SkipItems = false;
Appearing = false;
CloseButton = false;
BeginCount = 0;
PopupId = 0;
AutoFitFramesX = AutoFitFramesY = -1;
@ -3944,6 +3940,13 @@ static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size,
return pos;
}
static void SetWindowConditionAllowFlags(ImGuiWindow* window, ImGuiCond flags, bool enabled)
{
window->SetWindowPosAllowFlags = enabled ? (window->SetWindowPosAllowFlags | flags) : (window->SetWindowPosAllowFlags & ~flags);
window->SetWindowSizeAllowFlags = enabled ? (window->SetWindowSizeAllowFlags | flags) : (window->SetWindowSizeAllowFlags & ~flags);
window->SetWindowCollapsedAllowFlags = enabled ? (window->SetWindowCollapsedAllowFlags | flags) : (window->SetWindowCollapsedAllowFlags & ~flags);
}
ImGuiWindow* ImGui::FindWindowByName(const char* name)
{
ImGuiContext& g = *GImGui;
@ -3975,15 +3978,9 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
ImGuiIniData* settings = FindWindowSettings(name);
if (!settings)
{
settings = AddWindowSettings(name);
}
else
{
window->SetWindowPosAllowFlags &= ~ImGuiCond_FirstUseEver;
window->SetWindowSizeAllowFlags &= ~ImGuiCond_FirstUseEver;
window->SetWindowCollapsedAllowFlags &= ~ImGuiCond_FirstUseEver;
}
SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false);
if (settings->Pos.x != FLT_MAX)
{
@ -4039,7 +4036,10 @@ static ImVec2 CalcSizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size)
}
}
if (!(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysAutoResize)))
{
new_size = ImMax(new_size, g.Style.WindowMinSize);
new_size.y = ImMax(new_size.y, window->TitleBarHeight() + window->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); // Reduce artifacts with very small windows
}
return new_size;
}
@ -4154,13 +4154,14 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFrames == 1);
window->Appearing = (window_just_activated_by_user || window_just_appearing_after_hidden_for_resize);
window->CloseButton = (p_open != NULL);
// Process SetNextWindow***() calls
if (window->Appearing)
SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true);
bool window_pos_set_by_api = false, window_size_set_by_api = false;
if (g.SetNextWindowPosCond)
{
if (window->Appearing)
window->SetWindowPosAllowFlags |= ImGuiCond_Appearing;
window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) != 0;
if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosPivot) > 0.00001f)
{
@ -4178,8 +4179,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
}
if (g.SetNextWindowSizeCond)
{
if (window->Appearing)
window->SetWindowSizeAllowFlags |= ImGuiCond_Appearing;
window_size_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0;
SetWindowSize(window, g.SetNextWindowSizeVal, g.SetNextWindowSizeCond);
g.SetNextWindowSizeCond = 0;
@ -4195,8 +4194,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
}
if (g.SetNextWindowCollapsedCond)
{
if (window->Appearing)
window->SetWindowCollapsedAllowFlags |= ImGuiCond_Appearing;
SetWindowCollapsed(window, g.SetNextWindowCollapsedVal, g.SetNextWindowCollapsedCond);
g.SetNextWindowCollapsedCond = 0;
}
@ -4205,6 +4202,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
SetWindowFocus();
g.SetNextWindowFocus = false;
}
if (window->Appearing)
SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, false);
// When reusing window again multiple times a frame, just append content (don't need to setup again)
if (first_begin_of_the_frame)
@ -4315,7 +4314,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->SizeFull = CalcSizeFullWithConstraint(window, window->SizeFull);
window->Size = window->Collapsed ? window->TitleBarRect().GetSize() : window->SizeFull;
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup))
{
IM_ASSERT(window_size_set_by_api); // Submitted by BeginChild()
window->Size = window->SizeFull;
}
// SCROLLBAR STATUS
@ -4338,11 +4340,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->OrderWithinParent = parent_window->DC.ChildWindows.Size;
parent_window->DC.ChildWindows.push_back(window);
}
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup))
{
IM_ASSERT(window_size_set_by_api); // Submitted by BeginChild()
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api)
window->Pos = window->PosFloat = parent_window->DC.CursorPos;
}
const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFrames == 0);
if (window_pos_with_pivot)
@ -4809,13 +4808,43 @@ void ImGui::Scrollbar(ImGuiLayoutType direction)
// Render
const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab);
ImRect grab_rect;
if (horizontal)
window->DrawList->AddRectFilled(ImVec2(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y), ImVec2(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, bb.Max.y), grab_col, style.ScrollbarRounding);
grab_rect = ImRect(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y, ImMin(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, window_rect.Max.x), bb.Max.y);
else
window->DrawList->AddRectFilled(ImVec2(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm)), ImVec2(bb.Max.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels), grab_col, style.ScrollbarRounding);
grab_rect = ImRect(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm), bb.Max.x, ImMin(ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels, window_rect.Max.y));
window->DrawList->AddRectFilled(grab_rect.Min, grab_rect.Max, grab_col, style.ScrollbarRounding);
}
// Moving window to front of display (which happens to be back of our sorted list)
void ImGui::BringWindowToFront(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
if (g.Windows.back() == window)
return;
for (int i = 0; i < g.Windows.Size; i++)
if (g.Windows[i] == window)
{
g.Windows.erase(g.Windows.begin() + i);
g.Windows.push_back(window);
break;
}
}
void ImGui::BringWindowToBack(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
if (g.Windows[0] == window)
return;
for (int i = 0; i < g.Windows.Size; i++)
if (g.Windows[i] == window)
{
memmove(&g.Windows[1], &g.Windows[0], (size_t)i * sizeof(ImGuiWindow*));
g.Windows[0] = window;
break;
}
}
// Moving window to front of display and set focus (which happens to be back of our sorted list)
void ImGui::FocusWindow(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
@ -4827,7 +4856,7 @@ void ImGui::FocusWindow(ImGuiWindow* window)
if (!window)
return;
// And move its root window to the top of the pile
// Move the root window to the top of the pile
if (window->RootWindow)
window = window->RootWindow;
@ -4837,15 +4866,8 @@ void ImGui::FocusWindow(ImGuiWindow* window)
ClearActiveID();
// Bring to front
if ((window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) || g.Windows.back() == window)
return;
for (int i = 0; i < g.Windows.Size; i++)
if (g.Windows[i] == window)
{
g.Windows.erase(g.Windows.begin() + i);
break;
}
g.Windows.push_back(window);
if (!(window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus))
BringWindowToFront(window);
}
void ImGui::FocusPreviousWindow()
@ -9229,10 +9251,12 @@ bool ImGui::BeginMenuBar()
if (!(window->Flags & ImGuiWindowFlags_MenuBar))
return false;
ImGuiContext& g = *GImGui;
IM_ASSERT(!window->DC.MenuBarAppending);
BeginGroup(); // Save position
PushID("##menubar");
ImRect rect = window->MenuBarRect();
rect.Max.x = ImMax(rect.Min.x, rect.Max.x - g.Style.WindowRounding);
PushClipRect(ImVec2(ImFloor(rect.Min.x+0.5f), ImFloor(rect.Min.y + window->BorderSize + 0.5f)), ImVec2(ImFloor(rect.Max.x+0.5f), ImFloor(rect.Max.y+0.5f)), false);
window->DC.CursorPos = ImVec2(rect.Min.x + window->DC.MenuBarOffsetX, rect.Min.y);// + g.Style.FramePadding.y);
window->DC.LayoutType = ImGuiLayoutType_Horizontal;
@ -9283,6 +9307,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
{
// Menu inside an horizontal menu bar
// Selectable extend their highlight by half ItemSpacing in each direction.
// For ChildMenu, the popup position will be overwritten by the call to FindBestPopupWindowPos() in Begin()
popup_pos = ImVec2(pos.x - window->WindowPadding.x, pos.y - style.FramePadding.y + window->MenuBarHeight());
window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f);
PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f);

View File

@ -1074,7 +1074,7 @@ struct ImGuiStorage
{
ImGuiID key;
union { int val_i; float val_f; void* val_p; };
Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; }
Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; }
Pair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; }
Pair(ImGuiID _key, void* _val_p) { key = _key; val_p = _val_p; }
};
@ -1083,7 +1083,7 @@ struct ImGuiStorage
// - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N)
// - Set***() functions find pair, insertion on demand if missing.
// - Sorted insertion is costly, paid once. A typical frame shouldn't need to insert any new pair.
IMGUI_API void Clear();
void Clear() { Data.clear(); }
IMGUI_API int GetInt(ImGuiID key, int default_val = 0) const;
IMGUI_API void SetInt(ImGuiID key, int val);
IMGUI_API bool GetBool(ImGuiID key, bool default_val = false) const;

View File

@ -264,7 +264,7 @@ void ImDrawList::ClearFreeMemory()
_Channels.clear();
}
// Use macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug mode
// Using macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug builds
#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : GNullClipRect)
#define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : NULL)
@ -388,7 +388,7 @@ void ImDrawList::ChannelsSplit(int channels_count)
_Channels.resize(channels_count);
_ChannelsCount = channels_count;
// _Channels[] (24 bytes each) hold storage that we'll swap with this->_CmdBuffer/_IdxBuffer
// _Channels[] (24/32 bytes each) hold storage that we'll swap with this->_CmdBuffer/_IdxBuffer
// The content of _Channels[0] at this point doesn't matter. We clear it to make state tidy in a debugger but we don't strictly need to.
// When we switch to the next channel, we'll copy _CmdBuffer/_IdxBuffer into _Channels[0] and then _Channels[1] into _CmdBuffer/_IdxBuffer
memset(&_Channels[0], 0, sizeof(ImDrawChannel));
@ -1208,7 +1208,7 @@ ImFontConfig::ImFontConfig()
const int FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF = 90;
const int FONT_ATLAS_DEFAULT_TEX_DATA_H = 27;
const unsigned int FONT_ATLAS_DEFAULT_TEX_DATA_ID = 0x80000000;
const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] =
static const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] =
{
"..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX"
"..- -X.....X- X.X - X.X -X.....X - X.....X"
@ -1239,6 +1239,19 @@ const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF
" - XX XX - "
};
static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_Count_][3] =
{
// Pos ........ Size ......... Offset ......
{ ImVec2(0,3), ImVec2(12,19), ImVec2( 0, 0) }, // ImGuiMouseCursor_Arrow
{ ImVec2(13,0), ImVec2(7,16), ImVec2( 4, 8) }, // ImGuiMouseCursor_TextInput
{ ImVec2(31,0), ImVec2(23,23), ImVec2(11,11) }, // ImGuiMouseCursor_Move
{ ImVec2(21,0), ImVec2( 9,23), ImVec2( 5,11) }, // ImGuiMouseCursor_ResizeNS
{ ImVec2(55,18),ImVec2(23, 9), ImVec2(11, 5) }, // ImGuiMouseCursor_ResizeEW
{ ImVec2(73,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNESW
{ ImVec2(55,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNWSE
};
ImFontAtlas::ImFontAtlas()
{
TexID = NULL;
@ -1784,26 +1797,14 @@ static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas)
atlas->TexUvWhitePixel = ImVec2((r.X + 0.5f) * tex_uv_scale.x, (r.Y + 0.5f) * tex_uv_scale.y);
// Setup mouse cursors
const ImVec2 cursor_datas[ImGuiMouseCursor_Count_][3] =
{
// Pos ........ Size ......... Offset ......
{ ImVec2(0,3), ImVec2(12,19), ImVec2( 0, 0) }, // ImGuiMouseCursor_Arrow
{ ImVec2(13,0), ImVec2(7,16), ImVec2( 4, 8) }, // ImGuiMouseCursor_TextInput
{ ImVec2(31,0), ImVec2(23,23), ImVec2(11,11) }, // ImGuiMouseCursor_Move
{ ImVec2(21,0), ImVec2( 9,23), ImVec2( 5,11) }, // ImGuiMouseCursor_ResizeNS
{ ImVec2(55,18),ImVec2(23, 9), ImVec2(11, 5) }, // ImGuiMouseCursor_ResizeEW
{ ImVec2(73,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNESW
{ ImVec2(55,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNWSE
};
for (int type = 0; type < ImGuiMouseCursor_Count_; type++)
{
ImGuiMouseCursorData& cursor_data = GImGui->MouseCursorData[type];
ImVec2 pos = cursor_datas[type][0] + ImVec2((float)r.X, (float)r.Y);
const ImVec2 size = cursor_datas[type][1];
ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[type][0] + ImVec2((float)r.X, (float)r.Y);
const ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[type][1];
cursor_data.Type = type;
cursor_data.Size = size;
cursor_data.HotOffset = cursor_datas[type][2];
cursor_data.HotOffset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[type][2];
cursor_data.TexUvMin[0] = (pos) * tex_uv_scale;
cursor_data.TexUvMax[0] = (pos + size) * tex_uv_scale;
pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1;

View File

@ -728,6 +728,7 @@ struct IMGUI_API ImGuiWindow
bool Collapsed; // Set when collapsing window to become only title-bar
bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed)
bool Appearing; // Set during the frame where the window is appearing (or re-appearing)
bool CloseButton; // Set when the window has a close button (p_open != NULL)
int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
int AutoFitFramesX, AutoFitFramesY;
@ -808,6 +809,8 @@ namespace ImGui
IMGUI_API ImGuiWindow* GetParentWindow();
IMGUI_API ImGuiWindow* FindWindowByName(const char* name);
IMGUI_API void FocusWindow(ImGuiWindow* window);
IMGUI_API void BringWindowToFront(ImGuiWindow* window);
IMGUI_API void BringWindowToBack(ImGuiWindow* window);
IMGUI_API void Initialize();
IMGUI_API void EndFrame(); // Ends the ImGui frame. Automatically called by Render()! you most likely don't need to ever call that yourself directly. If you don't need to render you can call EndFrame() but you'll have wasted CPU already. If you don't need to render, don't create any windows instead!