1
0
mirror of https://github.com/ocornut/imgui.git synced 2024-11-12 02:00:58 +01:00

Merge branch 'master' into navigation

This commit is contained in:
omar 2017-11-29 23:49:17 +01:00
commit 81cbaef806
3 changed files with 69 additions and 66 deletions

111
imgui.cpp
View File

@ -681,8 +681,7 @@ static void AddDrawListToRenderList(ImVector<ImDrawList*>& out_rende
static void AddWindowToRenderList(ImVector<ImDrawList*>& out_render_list, ImGuiWindow* window);
static void AddWindowToSortedBuffer(ImVector<ImGuiWindow*>& out_sorted_windows, ImGuiWindow* window);
static ImGuiSettingsWindow* FindWindowSettings(const char* name);
static ImGuiSettingsWindow* AddWindowSettings(const char* name);
static ImGuiWindowSettings* AddWindowSettings(const char* name);
static void LoadIniSettingsFromDisk(const char* ini_filename);
static void LoadIniSettingsFromMemory(const char* buf);
@ -2089,7 +2088,7 @@ void ImGui::ItemSize(const ImVec2& size, float text_offset_y)
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.IndentX + window->DC.ColumnsOffsetX), (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);
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]
window->DC.PrevLineHeight = line_height;
@ -3276,9 +3275,9 @@ void ImGui::NewFrame()
Begin("Debug##Default");
}
static void* SettingsHandlerWindow_ReadOpenEntry(ImGuiContext&, const char* name)
static void* SettingsHandlerWindow_ReadOpen(ImGuiContext&, const char* name)
{
ImGuiSettingsWindow* settings = FindWindowSettings(name);
ImGuiWindowSettings* settings = ImGui::FindWindowSettings(ImHash(name, 0));
if (!settings)
settings = AddWindowSettings(name);
return (void*)settings;
@ -3286,7 +3285,7 @@ static void* SettingsHandlerWindow_ReadOpenEntry(ImGuiContext&, const char* name
static void SettingsHandlerWindow_ReadLine(ImGuiContext&, void* entry, const char* line)
{
ImGuiSettingsWindow* settings = (ImGuiSettingsWindow*)entry;
ImGuiWindowSettings* settings = (ImGuiWindowSettings*)entry;
float x, y;
int i;
if (sscanf(line, "Pos=%f,%f", &x, &y) == 2) settings->Pos = ImVec2(x, y);
@ -3302,9 +3301,9 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext& g, ImGuiTextBuffer* buf
ImGuiWindow* window = g.Windows[i];
if (window->Flags & ImGuiWindowFlags_NoSavedSettings)
continue;
ImGuiSettingsWindow* settings = FindWindowSettings(window->Name);
if (!settings) // This will only return NULL in the rare instance where the window was first created with ImGuiWindowFlags_NoSavedSettings then had the flag disabled later on. We don't bind settings in this case (bug #1000).
continue;
ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID);
if (!settings)
settings = AddWindowSettings(window->Name);
settings->Pos = window->Pos;
settings->Size = window->SizeFull;
settings->Collapsed = window->Collapsed;
@ -3315,7 +3314,7 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext& g, ImGuiTextBuffer* buf
buf->reserve(buf->size() + g.SettingsWindows.Size * 96); // ballpark reserve
for (int i = 0; i != g.SettingsWindows.Size; i++)
{
const ImGuiSettingsWindow* settings = &g.SettingsWindows[i];
const ImGuiWindowSettings* settings = &g.SettingsWindows[i];
if (settings->Pos.x == FLT_MAX)
continue;
const char* name = settings->Name;
@ -3339,7 +3338,7 @@ void ImGui::Initialize()
ImGuiSettingsHandler ini_handler;
ini_handler.TypeName = "Window";
ini_handler.TypeHash = ImHash("Window", 0, 0);
ini_handler.ReadOpenEntryFn = SettingsHandlerWindow_ReadOpenEntry;
ini_handler.ReadOpenFn = SettingsHandlerWindow_ReadOpen;
ini_handler.ReadLineFn = SettingsHandlerWindow_ReadLine;
ini_handler.WriteAllFn = SettingsHandlerWindow_WriteAll;
g.SettingsHandlers.push_front(ini_handler);
@ -3414,29 +3413,22 @@ void ImGui::Shutdown()
g.Initialized = false;
}
static ImGuiSettingsWindow* FindWindowSettings(const char* name)
ImGuiWindowSettings* ImGui::FindWindowSettings(ImGuiID id)
{
ImGuiContext& g = *GImGui;
ImGuiID id = ImHash(name, 0);
for (int i = 0; i != g.SettingsWindows.Size; i++)
{
ImGuiSettingsWindow* ini = &g.SettingsWindows[i];
if (ini->Id == id)
return ini;
}
if (g.SettingsWindows[i].Id == id)
return &g.SettingsWindows[i];
return NULL;
}
static ImGuiSettingsWindow* AddWindowSettings(const char* name)
static ImGuiWindowSettings* AddWindowSettings(const char* name)
{
ImGuiContext& g = *GImGui;
g.SettingsWindows.resize(g.SettingsWindows.Size + 1);
ImGuiSettingsWindow* settings = &g.SettingsWindows.back();
g.SettingsWindows.push_back(ImGuiWindowSettings());
ImGuiWindowSettings* settings = &g.SettingsWindows.back();
settings->Name = ImStrdup(name);
settings->Id = ImHash(name, 0);
settings->Collapsed = false;
settings->Pos = ImVec2(FLT_MAX,FLT_MAX);
settings->Size = ImVec2(0,0);
return settings;
}
@ -3451,6 +3443,15 @@ static void LoadIniSettingsFromDisk(const char* ini_filename)
ImGui::MemFree(file_data);
}
ImGuiSettingsHandler* ImGui::FindSettingsHandler(ImGuiID type_hash)
{
ImGuiContext& g = *GImGui;
for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++)
if (g.SettingsHandlers[handler_n].TypeHash == type_hash)
return &g.SettingsHandlers[handler_n];
return NULL;
}
// Zero-tolerance, no error reporting, cheap .ini parsing
static void LoadIniSettingsFromMemory(const char* buf_readonly)
{
@ -3492,11 +3493,8 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly)
name_start++; // Skip second '['
}
const ImGuiID type_hash = ImHash(type_start, 0, 0);
entry_handler = NULL;
for (int handler_n = 0; handler_n < g.SettingsHandlers.Size && entry_handler == NULL; handler_n++)
if (g.SettingsHandlers[handler_n].TypeHash == type_hash)
entry_handler = &g.SettingsHandlers[handler_n];
entry_data = entry_handler ? entry_handler->ReadOpenEntryFn(g, name_start) : NULL;
entry_handler = ImGui::FindSettingsHandler(type_hash);
entry_data = entry_handler ? entry_handler->ReadOpenFn(g, name_start) : NULL;
}
else if (entry_handler != NULL && entry_data != NULL)
{
@ -4984,21 +4982,15 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
window->PosFloat = ImVec2(60, 60);
window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y);
ImGuiSettingsWindow* settings = FindWindowSettings(name);
if (!settings)
settings = AddWindowSettings(name);
else
SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false);
if (settings->Pos.x != FLT_MAX)
if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID))
{
SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false);
window->PosFloat = settings->Pos;
window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y);
window->Collapsed = settings->Collapsed;
if (ImLengthSqr(settings->Size) > 0.00001f)
size = settings->Size;
}
if (ImLengthSqr(settings->Size) > 0.00001f)
size = settings->Size;
window->Size = window->SizeFull = size;
}
@ -5060,22 +5052,31 @@ static ImVec2 CalcSizeAutoFit(ImGuiWindow* window)
if ((flags & ImGuiWindowFlags_Tooltip) != 0)
{
// Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose.
size_auto_fit = window->SizeContents + window->WindowPadding - ImVec2(0.0f, style.ItemSpacing.y);
size_auto_fit = window->SizeContents;
}
else
{
// Handling case of auto fit window not fitting on the screen (on either axis): we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding.
size_auto_fit = ImClamp(window->SizeContents + window->WindowPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding));
size_auto_fit = ImClamp(window->SizeContents, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding));
ImVec2 size_auto_fit_after_constraint = CalcSizeFullWithConstraint(window, size_auto_fit);
if (size_auto_fit_after_constraint.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar))
size_auto_fit.y += style.ScrollbarSize;
if (size_auto_fit_after_constraint.y < window->SizeContents.y && !(flags & ImGuiWindowFlags_NoScrollbar))
size_auto_fit.x += style.ScrollbarSize;
size_auto_fit.y = ImMax(size_auto_fit.y - style.ItemSpacing.y, 0.0f);
}
return size_auto_fit;
}
static float GetScrollMaxX(ImGuiWindow* window)
{
return ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x));
}
static float GetScrollMaxY(ImGuiWindow* window)
{
return ImMax(0.0f, window->SizeContents.y - (window->SizeFull.y - window->ScrollbarSizes.y));
}
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window)
{
ImVec2 scroll = window->Scroll;
@ -5088,8 +5089,8 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window)
scroll = ImMax(scroll, ImVec2(0.0f, 0.0f));
if (!window->Collapsed && !window->SkipItems)
{
scroll.x = ImMin(scroll.x, ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x))); // == GetScrollMaxX for that window
scroll.y = ImMin(scroll.y, ImMax(0.0f, window->SizeContents.y - (window->SizeFull.y - window->ScrollbarSizes.y))); // == GetScrollMaxY for that window
scroll.x = ImMin(scroll.x, GetScrollMaxX(window));
scroll.y = ImMin(scroll.y, GetScrollMaxY(window));
}
return scroll;
}
@ -5274,6 +5275,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Update contents size from last frame for auto-fitting (unless explicitly specified)
window->SizeContents.x = (float)(int)((window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.x - window->Pos.x) + window->Scroll.x));
window->SizeContents.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.y - window->Pos.y) + window->Scroll.y));
window->SizeContents += window->WindowPadding;
// Hide popup/tooltip window when first appearing while we measure size (because we recycle them)
if (window->HiddenFrames > 0)
@ -5340,10 +5342,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Update scrollbar status (based on the Size that was effective during last frame or the auto-resized Size). We need to do this before manual resize (below) is effective.
if (!window->Collapsed)
{
window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->SizeFull.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar));
window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->SizeFull.y) && !(flags & ImGuiWindowFlags_NoScrollbar));
window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->SizeFull.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar));
if (window->ScrollbarX && !window->ScrollbarY)
window->ScrollbarY = (window->SizeContents.y > window->SizeFull.y + style.ItemSpacing.y - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar);
window->ScrollbarY = (window->SizeContents.y > window->SizeFull.y + style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar);
window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f);
}
@ -6660,14 +6662,12 @@ float ImGui::GetScrollY()
float ImGui::GetScrollMaxX()
{
ImGuiWindow* window = GetCurrentWindowRead();
return ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x));
return GetScrollMaxX(GImGui->CurrentWindow);
}
float ImGui::GetScrollMaxY()
{
ImGuiWindow* window = GetCurrentWindowRead();
return ImMax(0.0f, window->SizeContents.y - (window->SizeFull.y - window->ScrollbarSizes.y));
return GetScrollMaxY(GImGui->CurrentWindow);
}
void ImGui::SetScrollX(float scroll_x)
@ -6690,9 +6690,13 @@ void ImGui::SetScrollFromPosY(float pos_y, float center_y_ratio)
ImGuiWindow* window = GetCurrentWindow();
IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f);
window->ScrollTarget.y = (float)(int)(pos_y + window->Scroll.y);
if (center_y_ratio <= 0.0f && window->ScrollTarget.y <= window->WindowPadding.y) // Minor hack to make "scroll to top" take account of WindowPadding, else it would scroll to (WindowPadding.y - ItemSpacing.y)
window->ScrollTarget.y = 0.0f;
window->ScrollTargetCenterRatio.y = center_y_ratio;
// Minor hack to to make scrolling to top/bottom of window take account of WindowPadding, it looks more right to the user this way
if (center_y_ratio <= 0.0f && window->ScrollTarget.y <= window->WindowPadding.y)
window->ScrollTarget.y = 0.0f;
else if (center_y_ratio >= 1.0f && window->ScrollTarget.y >= window->SizeContents.y - window->WindowPadding.y + GImGui->Style.ItemSpacing.y)
window->ScrollTarget.y = window->SizeContents.y;
}
// center_y_ratio: 0.0f top of last item, 0.5f vertical center of last item, 1.0f bottom of last item.
@ -11594,7 +11598,6 @@ void ImGui::EndGroup()
ImGuiGroupData& group_data = window->DC.GroupStack.back();
ImRect group_bb(group_data.BackupCursorPos, window->DC.CursorMaxPos);
group_bb.Max.y -= g.Style.ItemSpacing.y; // Cancel out last vertical spacing because we are adding one ourselves.
group_bb.Max = ImMax(group_bb.Min, group_bb.Max);
window->DC.CursorPos = group_data.BackupCursorPos;
@ -12233,7 +12236,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImGui::BulletText("Pos: (%.1f,%.1f), Size: (%.1f,%.1f), SizeContents (%.1f,%.1f)", window->Pos.x, window->Pos.y, window->Size.x, window->Size.y, window->SizeContents.x, window->SizeContents.y);
if (ImGui::IsItemHovered())
GImGui->OverlayDrawList.AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255,255,0,255));
ImGui::BulletText("Scroll: (%.2f,%.2f)", window->Scroll.x, window->Scroll.y);
ImGui::BulletText("Scroll: (%.2f/%.2f,%.2f/%.2f)", window->Scroll.x, GetScrollMaxX(window), window->Scroll.y, GetScrollMaxY(window));
ImGui::BulletText("Active: %d, WriteAccessed: %d", window->Active, window->WriteAccessed);
ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask);
ImGui::BulletText("NavRectRel[0]: (%.1f,%.1f)(%.1f,%.1f)", window->NavRectRel[0].Min.x, window->NavRectRel[0].Min.y, window->NavRectRel[0].Max.x, window->NavRectRel[0].Max.y);

View File

@ -2518,7 +2518,7 @@ struct ExampleAppConsole
ImGui::PopStyleVar();
ImGui::Separator();
ImGui::BeginChild("ScrollingRegion", ImVec2(0,-ImGui::GetItemsLineHeightWithSpacing()), false, ImGuiWindowFlags_HorizontalScrollbar);
ImGui::BeginChild("ScrollingRegion", ImVec2(0, -ImGui::GetStyle().ItemSpacing.y - ImGui::GetItemsLineHeightWithSpacing()), false, ImGuiWindowFlags_HorizontalScrollbar); // Leave room for 1 separator + 1 InputText
if (ImGui::BeginPopupContextWindow())
{
if (ImGui::Selectable("Clear")) ClearLog();
@ -2848,11 +2848,9 @@ static void ShowExampleAppLayout(bool* p_open)
ImGui::Separator();
ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ");
ImGui::EndChild();
ImGui::BeginChild("buttons");
if (ImGui::Button("Revert")) {}
ImGui::SameLine();
if (ImGui::Button("Save")) {}
ImGui::EndChild();
if (ImGui::Button("Revert")) {}
ImGui::SameLine();
if (ImGui::Button("Save")) {}
ImGui::EndGroup();
}
ImGui::End();

View File

@ -39,10 +39,10 @@ struct ImGuiGroupData;
struct ImGuiSimpleColumns;
struct ImGuiDrawContext;
struct ImGuiTextEditState;
struct ImGuiSettingsWindow;
struct ImGuiMouseCursorData;
struct ImGuiPopupRef;
struct ImGuiWindow;
struct ImGuiWindowSettings;
typedef int ImGuiLayoutType; // enum: horizontal or vertical // enum ImGuiLayoutType_
typedef int ImGuiButtonFlags; // flags: for ButtonEx(), ButtonBehavior() // enum ImGuiButtonFlags_
@ -390,7 +390,7 @@ struct IMGUI_API ImGuiTextEditState
};
// Data saved in imgui.ini file
struct ImGuiSettingsWindow
struct ImGuiWindowSettings
{
char* Name;
ImGuiID Id;
@ -398,14 +398,14 @@ struct ImGuiSettingsWindow
ImVec2 Size;
bool Collapsed;
ImGuiSettingsWindow() { Name = NULL; Id = 0; Pos = Size = ImVec2(0,0); Collapsed = false; }
ImGuiWindowSettings() { Name = NULL; Id = 0; Pos = Size = ImVec2(0,0); Collapsed = false; }
};
struct ImGuiSettingsHandler
{
const char* TypeName; // Short description stored in .ini file. Disallowed characters: '[' ']'
ImGuiID TypeHash; // == ImHash(TypeName, 0, 0)
void* (*ReadOpenEntryFn)(ImGuiContext& ctx, const char* name);
void* (*ReadOpenFn)(ImGuiContext& ctx, const char* name);
void (*ReadLineFn)(ImGuiContext& ctx, void* entry, const char* line);
void (*WriteAllFn)(ImGuiContext& ctx, ImGuiTextBuffer* out_buf);
};
@ -557,7 +557,7 @@ struct ImGuiContext
// Settings
float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero
ImVector<ImGuiSettingsWindow> SettingsWindows; // .ini settings for ImGuiWindow
ImVector<ImGuiWindowSettings> SettingsWindows; // .ini settings for ImGuiWindow
ImVector<ImGuiSettingsHandler> SettingsHandlers; // List of .ini settings handlers
// Logging
@ -903,7 +903,9 @@ namespace ImGui
IMGUI_API void Initialize();
IMGUI_API void MarkIniSettingsDirty();
IMGUI_API void MarkIniSettingsDirty();
IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(ImGuiID type_id);
IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id);
IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window);
IMGUI_API ImGuiID GetActiveID();