New and better Set[Next]Window(Pos|Size|Collapsed) API.
Removed rarely useful SetNewWindowDefaultPos() in favor of new API.
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index c6ec87f..252b8b6 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -588,7 +588,7 @@
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (show_test_window)
{
- ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
+ ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCondition_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
ImGui::ShowTestWindow(&show_test_window);
}
diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp
index 9da31d2..fe4f15d 100644
--- a/examples/directx9_example/main.cpp
+++ b/examples/directx9_example/main.cpp
@@ -330,7 +330,7 @@
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (show_test_window)
{
- ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
+ ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCondition_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
}
diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp
index 41ef522..2687da9 100644
--- a/examples/opengl3_example/main.cpp
+++ b/examples/opengl3_example/main.cpp
@@ -360,7 +360,7 @@
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (show_test_window)
{
- ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call this, because positions are saved in .ini file. Here we just want to make the demo initial state a bit more friendly!
+ ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCondition_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
}
diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp
index 069fc87..34dd1da 100644
--- a/examples/opengl_example/main.cpp
+++ b/examples/opengl_example/main.cpp
@@ -293,7 +293,7 @@
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (show_test_window)
{
- ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call this, because positions are saved in .ini file. Here we just want to make the demo initial state a bit more friendly!
+ ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCondition_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
}
diff --git a/imgui.cpp b/imgui.cpp
index 13303a2..c890a55 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -117,6 +117,7 @@
Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix.
Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
+ - 2014/12/10 (1.18) removed SetNewWindowDefaultPos() in favor of new generic API SetNextWindowPos(pos, ImGuiSetCondition_FirstUseEver)
- 2014/11/28 (1.17) moved IO.Font*** options to inside the IO.Font-> structure.
- 2014/11/26 (1.17) reworked syntax of IMGUI_ONCE_UPON_A_FRAME helper macro to increase compiler compatibility
- 2014/11/07 (1.15) renamed IsHovered() to IsItemHovered()
@@ -773,9 +774,14 @@
bool ActiveIdIsAlive;
float SettingsDirtyTimer;
ImVector<ImGuiIniData*> Settings;
- ImVec2 NewWindowDefaultPos;
ImVector<ImGuiColMod> ColorModifiers;
ImVector<ImGuiStyleMod> StyleModifiers;
+ ImVec2 SetNextWindowPosVal;
+ ImGuiSetCondition SetNextWindowPosCond;
+ ImVec2 SetNextWindowSizeVal;
+ ImGuiSetCondition SetNextWindowSizeCond;
+ bool SetNextWindowCollapsedVal;
+ ImGuiSetCondition SetNextWindowCollapsedCond;
// Render
ImVector<ImDrawList*> RenderDrawLists;
@@ -806,7 +812,12 @@
HoveredRootWindow = NULL;
ActiveIdIsAlive = false;
SettingsDirtyTimer = 0.0f;
- NewWindowDefaultPos = ImVec2(60, 60);
+ SetNextWindowPosVal = ImVec2(0.0f, 0.0f);
+ SetNextWindowPosCond = 0;
+ SetNextWindowSizeVal = ImVec2(0.0f, 0.0f);
+ SetNextWindowSizeCond = 0;
+ SetNextWindowCollapsedVal = false;
+ SetNextWindowCollapsedCond = 0;
SliderAsInputTextId = 0;
ActiveComboID = 0;
memset(Tooltip, 0, sizeof(Tooltip));
@@ -839,6 +850,9 @@
bool SkipItems; // == Visible && !Collapsed
int AutoFitFrames;
bool AutoFitOnlyGrows;
+ int SetWindowPosAllowFlags; // bit ImGuiSetCondition_*** specify if SetWindowPos() call is allowed with this particular flag.
+ int SetWindowSizeAllowFlags; // bit ImGuiSetCondition_*** specify if SetWindowSize() call is allowed with this particular flag.
+ int SetWindowCollapsedAllowFlags; // bit ImGuiSetCondition_*** specify if SetWindowCollapsed() call is allowed with this particular flag.
ImGuiDrawContext DC;
ImVector<ImGuiID> IDStack;
@@ -859,7 +873,7 @@
int FocusIdxTabRequestNext; // "
public:
- ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_size);
+ ImGuiWindow(const char* name);
~ImGuiWindow();
ImGuiID GetID(const char* str);
@@ -1103,15 +1117,14 @@
//-----------------------------------------------------------------------------
-ImGuiWindow::ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_size)
+ImGuiWindow::ImGuiWindow(const char* name)
{
Name = ImStrdup(name);
ID = GetID(name);
IDStack.push_back(ID);
- PosFloat = default_pos;
- Pos = ImVec2((float)(int)PosFloat.x, (float)(int)PosFloat.y);
- Size = SizeFull = default_size;
+ PosFloat = Pos = ImVec2(0.0f, 0.0f);
+ Size = SizeFull = ImVec2(0.0f, 0.0f);
SizeContentsFit = ImVec2(0.0f, 0.0f);
ScrollY = 0.0f;
NextScrollY = 0.0f;
@@ -1122,6 +1135,8 @@
SkipItems = false;
AutoFitFrames = -1;
AutoFitOnlyGrows = false;
+ SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiSetCondition_Always | ImGuiSetCondition_FirstUseThisSession | ImGuiSetCondition_FirstUseEver;
+
LastFrameDrawn = -1;
ItemWidthDefault = 0.0f;
FontWindowScale = 1.0f;
@@ -1240,20 +1255,24 @@
static ImGuiIniData* FindWindowSettings(const char* name)
{
ImGuiState& g = GImGui;
-
for (size_t i = 0; i != g.Settings.size(); i++)
{
ImGuiIniData* ini = g.Settings[i];
if (ImStricmp(ini->Name, name) == 0)
return ini;
}
+ return NULL;
+}
+
+static ImGuiIniData* AddWindowSettings(const char* name)
+{
ImGuiIniData* ini = (ImGuiIniData*)ImGui::MemAlloc(sizeof(ImGuiIniData));
new(ini) ImGuiIniData();
ini->Name = ImStrdup(name);
ini->Collapsed = false;
ini->Pos = ImVec2(FLT_MAX,FLT_MAX);
ini->Size = ImVec2(0,0);
- g.Settings.push_back(ini);
+ GImGui.Settings.push_back(ini);
return ini;
}
@@ -1310,6 +1329,8 @@
char name[64];
ImFormatString(name, IM_ARRAYSIZE(name), "%.*s", line_end-line_start-2, line_start+1);
settings = FindWindowSettings(name);
+ if (!settings)
+ settings = AddWindowSettings(name);
}
else if (settings)
{
@@ -2026,13 +2047,6 @@
va_end(args);
}
-// Position new window if they don't have position setting in the .ini file. Rarely useful (used by the sample applications).
-void ImGui::SetNewWindowDefaultPos(const ImVec2& pos)
-{
- ImGuiState& g = GImGui;
- g.NewWindowDefaultPos = pos;
-}
-
float ImGui::GetTime()
{
return GImGui.Time;
@@ -2121,7 +2135,10 @@
}
}
-// Push a new ImGui window to add widgets to. This can be called multiple times with the same window to append contents
+// Push a new ImGui window to add widgets to.
+// A default window called "Debug" is automatically stacked at the beginning of every frame.
+// This can be called multiple times with the same window name to append content to the same window.
+// Passing non-zero 'size' is roughly equivalent to calling SetNextWindowSize(size, ImGuiSetCondition_FirstUseEver) prior to calling Begin().
bool ImGui::Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWindowFlags flags)
{
ImGuiState& g = GImGui;
@@ -2136,17 +2153,30 @@
{
// Tooltip and child windows don't store settings
window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow));
- new(window) ImGuiWindow(name, ImVec2(0,0), size);
+ new(window) ImGuiWindow(name);
+
+ window->Size = window->SizeFull = size;
}
else
{
// Normal windows store settings in .ini file
- ImGuiIniData* settings = FindWindowSettings(name);
- if (settings && ImLength(settings->Size) > 0.0f && !(flags & ImGuiWindowFlags_NoResize))// && ImLengthsize) == 0.0f)
- size = settings->Size;
-
window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow));
- new(window) ImGuiWindow(name, g.NewWindowDefaultPos, size);
+ new(window) ImGuiWindow(name);
+
+ window->PosFloat = ImVec2(60, 60);
+ window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y);
+
+ ImGuiIniData* settings = FindWindowSettings(name);
+ if (!settings)
+ {
+ settings = AddWindowSettings(name);
+ }
+ else
+ {
+ window->SetWindowPosAllowFlags &= ~ImGuiSetCondition_FirstUseEver;
+ window->SetWindowSizeAllowFlags &= ~ImGuiSetCondition_FirstUseEver;
+ window->SetWindowCollapsedAllowFlags &= ~ImGuiSetCondition_FirstUseEver;
+ }
if (settings->Pos.x != FLT_MAX)
{
@@ -2154,6 +2184,10 @@
window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y);
window->Collapsed = settings->Collapsed;
}
+
+ if (ImLength(settings->Size) > 0.0f && !(flags & ImGuiWindowFlags_NoResize))
+ size = settings->Size;
+ window->Size = window->SizeFull = size;
}
g.Windows.push_back(window);
}
@@ -2162,6 +2196,25 @@
g.CurrentWindowStack.push_back(window);
g.CurrentWindow = window;
+ // Process SetNextWindow***() calls
+ if (g.SetNextWindowPosCond)
+ {
+ const ImVec2 backup_cursor_pos = window->DC.CursorPos;
+ ImGui::SetWindowPos(g.SetNextWindowPosVal, g.SetNextWindowPosCond);
+ window->DC.CursorPos = backup_cursor_pos;
+ g.SetNextWindowPosCond = 0;
+ }
+ if (g.SetNextWindowSizeCond)
+ {
+ ImGui::SetWindowSize(g.SetNextWindowSizeVal, g.SetNextWindowSizeCond);
+ g.SetNextWindowSizeCond = 0;
+ }
+ if (g.SetNextWindowCollapsedCond)
+ {
+ ImGui::SetWindowCollapsed(g.SetNextWindowCollapsedVal, g.SetNextWindowCollapsedCond);
+ g.SetNextWindowCollapsedCond = 0;
+ }
+
// Find root
size_t root_idx = g.CurrentWindowStack.size() - 1;
while (root_idx > 0)
@@ -2797,15 +2850,20 @@
return window->Pos;
}
-void ImGui::SetWindowPos(const ImVec2& pos)
+void ImGui::SetWindowPos(const ImVec2& pos, ImGuiSetCondition cond)
{
ImGuiWindow* window = GetCurrentWindow();
+
+ // Test condition (NB: bit 0 is always true) and clear flags for next time
+ if (cond && (window->SetWindowPosAllowFlags & cond) == 0)
+ return;
+ window->SetWindowPosAllowFlags &= ~(ImGuiSetCondition_FirstUseThisSession | ImGuiSetCondition_FirstUseEver);
+
+ // Set
const ImVec2 old_pos = window->Pos;
window->PosFloat = pos;
window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y);
-
- // If we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor
- window->DC.CursorPos += (window->Pos - old_pos);
+ window->DC.CursorPos += (window->Pos - old_pos); // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor
}
ImVec2 ImGui::GetWindowSize()
@@ -2814,9 +2872,16 @@
return window->Size;
}
-void ImGui::SetWindowSize(const ImVec2& size)
+void ImGui::SetWindowSize(const ImVec2& size, ImGuiSetCondition cond)
{
ImGuiWindow* window = GetCurrentWindow();
+
+ // Test condition (NB: bit 0 is always true) and clear flags for next time
+ if (cond && (window->SetWindowSizeAllowFlags & cond) == 0)
+ return;
+ window->SetWindowSizeAllowFlags &= ~(ImGuiSetCondition_FirstUseThisSession | ImGuiSetCondition_FirstUseEver);
+
+ // Set
if (ImLength(size) < 0.001f)
{
window->AutoFitFrames = 2;
@@ -2825,9 +2890,44 @@
else
{
window->SizeFull = size;
+ window->AutoFitFrames = 0;
}
}
+void ImGui::SetWindowCollapsed(bool collapsed, ImGuiSetCondition cond)
+{
+ ImGuiWindow* window = GetCurrentWindow();
+
+ // Test condition (NB: bit 0 is always true) and clear flags for next time
+ if (cond && (window->SetWindowCollapsedAllowFlags & cond) == 0)
+ return;
+ window->SetWindowCollapsedAllowFlags &= ~(ImGuiSetCondition_FirstUseThisSession | ImGuiSetCondition_FirstUseEver);
+
+ // Set
+ window->Collapsed = collapsed;
+}
+
+void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiSetCondition cond)
+{
+ ImGuiState& g = GImGui;
+ g.SetNextWindowPosVal = pos;
+ g.SetNextWindowPosCond = cond ? cond : ImGuiSetCondition_Always;
+}
+
+void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiSetCondition cond)
+{
+ ImGuiState& g = GImGui;
+ g.SetNextWindowSizeVal = size;
+ g.SetNextWindowSizeCond = cond ? cond : ImGuiSetCondition_Always;
+}
+
+void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiSetCondition cond)
+{
+ ImGuiState& g = GImGui;
+ g.SetNextWindowCollapsedVal = collapsed;
+ g.SetNextWindowCollapsedCond = cond ? cond : ImGuiSetCondition_Always;
+}
+
ImVec2 ImGui::GetContentRegionMax()
{
ImGuiWindow* window = GetCurrentWindow();
@@ -6555,7 +6655,7 @@
*ref = g.Style;
}
- ImGui::PushItemWidth(ImGui::GetWindowWidth()*0.55f);
+ ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.55f);
if (ImGui::TreeNode("Sizes"))
{
@@ -6943,7 +7043,7 @@
ImGui::PushItemWidth(100);
goto_line |= ImGui::InputInt("##Line", &line, 0, 0, ImGuiInputTextFlags_EnterReturnsTrue);
ImGui::PopItemWidth();
- ImGui::BeginChild("Sub1", ImVec2(ImGui::GetWindowWidth()*0.5f,300));
+ ImGui::BeginChild("Sub1", ImVec2(ImGui::GetWindowWidth() * 0.5f,300));
for (int i = 0; i < 100; i++)
{
ImGui::Text("%04d: scrollable region", i);
diff --git a/imgui.h b/imgui.h
index 8ce585e..2d82d1e 100644
--- a/imgui.h
+++ b/imgui.h
@@ -37,6 +37,7 @@
typedef int ImGuiKey; // enum ImGuiKey_
typedef int ImGuiColorEditMode; // enum ImGuiColorEditMode_
typedef int ImGuiWindowFlags; // enum ImGuiWindowFlags_
+typedef int ImGuiSetCondition; // enum ImGuiSetCondition_
typedef int ImGuiInputTextFlags; // enum ImGuiInputTextFlags_
struct ImGuiTextEditCallbackData;
@@ -127,7 +128,7 @@
// - struct ImGuiTextBuffer // Text buffer for logging/accumulating text
// - struct ImGuiStorage // Custom key value storage (if you need to alter open/close states manually)
// - struct ImDrawList // Draw command list
-// - struct ImBitmapFont // Bitmap font loader
+// - struct ImFont // Bitmap font loader
// ImGui End-user API
// In a namespace so that user can add extra functions (e.g. Value() helpers for your vector or common types)
@@ -149,11 +150,6 @@
IMGUI_API void BeginChild(const char* str_id, ImVec2 size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). on each axis.
IMGUI_API void EndChild();
IMGUI_API bool GetWindowIsFocused();
- IMGUI_API ImVec2 GetWindowSize();
- IMGUI_API float GetWindowWidth();
- IMGUI_API void SetWindowSize(const ImVec2& size); // set to ImVec2(0,0) to force an auto-fit
- IMGUI_API ImVec2 GetWindowPos(); // you should rarely need/care about the window position, but it can be useful if you want to use your own drawing.
- IMGUI_API void SetWindowPos(const ImVec2& pos); // set current window pos.
IMGUI_API ImVec2 GetContentRegionMax(); // window or current column boundaries
IMGUI_API ImVec2 GetWindowContentRegionMin(); // window boundaries
IMGUI_API ImVec2 GetWindowContentRegionMax();
@@ -161,11 +157,22 @@
IMGUI_API ImFont* GetWindowFont();
IMGUI_API float GetWindowFontSize();
IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows.
+ IMGUI_API ImVec2 GetWindowPos(); // you should rarely need/care about the window position, but it can be useful if you want to do your own drawing.
+ IMGUI_API ImVec2 GetWindowSize(); // get current window position.
+ IMGUI_API float GetWindowWidth();
+ IMGUI_API bool GetWindowCollapsed();
+ IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiSetCondition cond = 0); // set current window position.
+ IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiSetCondition cond = 0); // set current window size. set to ImVec2(0,0) to force an auto-fit
+ IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiSetCondition cond = 0); // set current window collapsed state.
+ IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiSetCondition cond = 0); // set next window position.
+ IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiSetCondition cond = 0); // set next window size. set to ImVec2(0,0) to force an auto-fit
+ IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiSetCondition cond = 0); // set next window collapsed state.
+
IMGUI_API void SetScrollPosHere(); // adjust scrolling position to center into the current cursor position.
- IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use 'offset' to access sub components of a multiple component widget.
+ IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget.
IMGUI_API void SetTreeStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it).
IMGUI_API ImGuiStorage* GetTreeStateStorage();
-
+
IMGUI_API void PushItemWidth(float item_width); // width of items for the common item+label case. default to ~2/3 of windows width.
IMGUI_API void PopItemWidth();
IMGUI_API float GetItemWidth();
@@ -279,7 +286,6 @@
IMGUI_API void LogToClipboard(int max_depth = -1);
// Utilities
- IMGUI_API void SetNewWindowDefaultPos(const ImVec2& pos); // set position of window that do
IMGUI_API bool IsItemHovered(); // was the last item active area hovered by mouse?
IMGUI_API bool IsItemFocused(); // was the last item focused for keyboard input?
IMGUI_API ImVec2 GetItemBoxMin(); // get bounding box of last item
@@ -422,6 +428,15 @@
ImGuiColorEditMode_HEX = 2
};
+// Condition flags for ImGui::SetWindow***() and SetNextWindow***() functions
+// Those functions treat 0 as a shortcut to ImGuiSetCondition_Always
+enum ImGuiSetCondition_
+{
+ ImGuiSetCondition_Always = 1 << 0, // Set the variable
+ ImGuiSetCondition_FirstUseThisSession = 1 << 1, // Only set the variable on the first call for this window (once per session)
+ ImGuiSetCondition_FirstUseEver = 1 << 2, // Only set the variable if the window doesn't exist in the .ini file
+};
+
struct ImGuiStyle
{
float Alpha; // Global alpha applies to everything in ImGui