Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stacklayout: fix CI (on feature/layout-external) #5

Open
wants to merge 4 commits into
base: feature/layout-external
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ jobs:
MSBUILD_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\
steps:
- uses: actions/checkout@v3
- name: Append imgui_stacklayout.cpp to imgui.cpp (Windows)
shell: cmd
run: |
type imgui_stacklayout.cpp >> imgui.cpp
del imgui_stacklayout.cpp

- name: Install Dependencies
shell: powershell
Expand Down Expand Up @@ -210,6 +215,8 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Append imgui_stacklayout.cpp to imgui.cpp
run: cat imgui_stacklayout.cpp >> imgui.cpp && rm imgui_stacklayout.cpp

- name: Install Dependencies
run: |
Expand Down Expand Up @@ -403,6 +410,8 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Append imgui_stacklayout.cpp to imgui.cpp
run: cat imgui_stacklayout.cpp >> imgui.cpp && rm imgui_stacklayout.cpp

- name: Install Dependencies
run: |
Expand Down Expand Up @@ -463,6 +472,8 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Append imgui_stacklayout.cpp to imgui.cpp
run: cat imgui_stacklayout.cpp >> imgui.cpp && rm imgui_stacklayout.cpp

- name: Build example_apple_metal
run: |
Expand All @@ -473,6 +484,8 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Append imgui_stacklayout.cpp to imgui.cpp
run: cat imgui_stacklayout.cpp >> imgui.cpp && rm imgui_stacklayout.cpp

- name: Install Dependencies
run: |
Expand Down Expand Up @@ -500,6 +513,8 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Append imgui_stacklayout.cpp to imgui.cpp
run: cat imgui_stacklayout.cpp >> imgui.cpp && rm imgui_stacklayout.cpp

- name: Build example_android_opengl3
run: |
Expand Down
2 changes: 1 addition & 1 deletion examples/example_emscripten_wgpu/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ static bool InitWGPU()
wgpu::Surface surface = instance.CreateSurface(&surface_desc);
wgpu::Adapter adapter = {};
wgpu_preferred_fmt = (WGPUTextureFormat)surface.GetPreferredFormat(adapter);
wgpu_surface = surface.Release();
wgpu_surface = surface.MoveToCHandle();

return true;
}
Expand Down
43 changes: 39 additions & 4 deletions imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1201,6 +1201,7 @@ ImGuiStyle::ImGuiStyle()
ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar
GrabMinSize = 12.0f; // Minimum width/height of a grab box for slider/scrollbar
GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
LayoutAlign = 0.5f; // Element alignment inside horizontal and vertical layouts (0.0f - left/top, 1.0f - right/bottom, 0.5f - center).
LogSliderDeadzone = 4.0f; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero.
TabRounding = 4.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
TabBorderSize = 0.0f; // Thickness of border around tabs.
Expand Down Expand Up @@ -3119,6 +3120,7 @@ static const ImGuiDataVarInfo GStyleVarInfo[] =
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, SeparatorTextBorderSize)},// ImGuiStyleVar_SeparatorTextBorderSize
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextAlign) }, // ImGuiStyleVar_SeparatorTextAlign
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextPadding) }, // ImGuiStyleVar_SeparatorTextPadding
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, LayoutAlign) }, // ImGuiStyleVar_LayoutAlign
};

const ImGuiDataVarInfo* ImGui::GetStyleVarInfo(ImGuiStyleVar idx)
Expand Down Expand Up @@ -9789,6 +9791,10 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
g.NextItemData.Flags = ImGuiNextItemDataFlags_None;
g.NextItemData.ItemFlags = ImGuiItemFlags_None;

#if IMGUI_HAS_STACK_LAYOUT
ImGuiInternal::UpdateItemRect(window->ID, bb.Min, bb.Max);
#endif

#ifdef IMGUI_ENABLE_TEST_ENGINE
if (id != 0)
IMGUI_TEST_ENGINE_ITEM_ADD(id, g.LastItemData.NavRect, &g.LastItemData);
Expand Down Expand Up @@ -9873,6 +9879,38 @@ void ImGui::ItemSize(const ImVec2& size, float text_baseline_y)
if (window->SkipItems)
return;

#if IMGUI_HAS_STACK_LAYOUT
ImGuiLayoutType layout_type = ImGuiInternal::GetCurrentLayoutType(window->ID);
#else
ImGuiLayoutType layout_type = window->DC.LayoutType;
#endif

//if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorPos, 3.0f, IM_COL32(255,255,0,255), 4); // [DEBUG] Widget position

// Stack Layouts: Handle horizontal case first to simplify merge in case code handling vertical changes.
if (layout_type == ImGuiLayoutType_Horizontal)
{
const float line_width = ImMax(window->DC.CurrLineSize.x, size.x);

// Always align ourselves on pixel boundaries
//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.x = window->DC.CursorPos.x;
window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y + size.y;
window->DC.CursorPos.x = IM_TRUNC(window->DC.CursorPos.x + line_width + g.Style.ItemSpacing.x);
window->DC.CursorPos.y = IM_TRUNC(window->DC.CursorPosPrevLine.y - size.y);
window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPos.x - g.Style.ItemSpacing.x);
window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPosPrevLine.y);
//if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG]

window->DC.PrevLineSize.x = line_width;
window->DC.PrevLineSize.y = 0.0f;
window->DC.CurrLineSize.x = 0.0f;
window->DC.PrevLineTextBaseOffset = ImMax(window->DC.CurrLineTextBaseOffset, text_baseline_y);
window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset;
window->DC.IsSameLine = window->DC.IsSetPos = false;
return;
}

// We increase the height in this function to accommodate for baseline offset.
// In theory we should be offsetting the starting position (window->DC.CursorPos), that will be the topic of a larger refactor,
// but since ItemSize() is not yet an API that moves the cursor (to handle e.g. wrapping) enlarging the height has the same effect.
Expand All @@ -9891,15 +9929,12 @@ void ImGui::ItemSize(const ImVec2& size, float text_baseline_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.PrevLineSize.x = 0.0f;
window->DC.PrevLineSize.y = line_height;
window->DC.CurrLineSize.y = 0.0f;
window->DC.PrevLineTextBaseOffset = ImMax(window->DC.CurrLineTextBaseOffset, text_baseline_y);
window->DC.CurrLineTextBaseOffset = 0.0f;
window->DC.IsSameLine = window->DC.IsSetPos = false;

// Horizontal layout mode
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
SameLine();
}

// Gets back to previous line and continue with horizontal layout
Expand Down
7 changes: 7 additions & 0 deletions imgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define IMGUI_VERSION "1.90.2 WIP"
#define IMGUI_VERSION_NUM 19014
#define IMGUI_HAS_TABLE
#define IMGUI_HAS_STACK_LAYOUT 1 // Stack-Layout PR #846

/*

Expand Down Expand Up @@ -1573,6 +1574,7 @@ enum ImGuiStyleVar_
ImGuiStyleVar_SeparatorTextBorderSize,// float SeparatorTextBorderSize
ImGuiStyleVar_SeparatorTextAlign, // ImVec2 SeparatorTextAlign
ImGuiStyleVar_SeparatorTextPadding,// ImVec2 SeparatorTextPadding
ImGuiStyleVar_LayoutAlign, // float LayoutAlign
ImGuiStyleVar_COUNT
};

Expand Down Expand Up @@ -1995,6 +1997,7 @@ struct ImGuiStyle
float ScrollbarRounding; // Radius of grab corners for scrollbar.
float GrabMinSize; // Minimum width/height of a grab box for slider/scrollbar.
float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
float LayoutAlign; // Element alignment inside horizontal and vertical layouts (0.0f - left/top, 1.0f - right/bottom, 0.5f - center).
float LogSliderDeadzone; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero.
float TabRounding; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
float TabBorderSize; // Thickness of border around tabs.
Expand Down Expand Up @@ -3288,6 +3291,10 @@ enum ImGuiModFlags_ { ImGuiModFlags_None = 0, ImGuiModFlags_Ctrl = ImGuiMod_Ctrl
#pragma warning (pop)
#endif

#if IMGUI_HAS_STACK_LAYOUT
#include "imgui_stacklayout.h"
#endif

// Include imgui_user.h at the end of imgui.h
// May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included.
#ifdef IMGUI_INCLUDE_IMGUI_USER_H
Expand Down
150 changes: 150 additions & 0 deletions imgui_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3579,6 +3579,156 @@ static void ShowDemoWindowLayout()

ImGui::TreePop();
}

#if IMGUI_HAS_STACK_LAYOUT
IMGUI_DEMO_MARKER("Layout/Stack Layout");
if (ImGui::TreeNode("Stack Layout"))
{
static bool widget_a = true, widget_b = true, widget_c = true;
static bool spring_a = true, spring_ab = true, spring_bc = true, spring_c = true;
static bool minimize_width = false, minimize_height = true;
static bool horizontal = true, draw_springs = true;
static ImVec2 item_spacing = ImGui::GetStyle().ItemSpacing;
static float a_c_spring_weight = 0.0f;
static float ab_spring_weight = 0.5f;
static float alignment = 0.5f;

struct funcs
{
static void VisibleSpring(float spring_weight)
{
ImGui::Spring(spring_weight);
if (!draw_springs)
return;

ImVec2 rect_min = ImGui::GetItemRectMin();
ImVec2 rect_max = ImGui::GetItemRectMax();

ImVec2 rect_size = ImGui::GetItemRectSize();
if (rect_size.x <= 0.0f && rect_size.y <= 0.0f)
return;

// Draw zig-zag
float width = 0.0f, spacing = 0.0f;
ImVec2 direction, origin;
ImVec2 spacing_min, spring_max;

if (horizontal)
{
spacing = floorf(item_spacing.x);
width = rect_size.x - spacing;
origin = ImVec2(floorf(rect_min.x), floorf(rect_min.y + (rect_max.y - rect_min.y) / 2));
direction = ImVec2(1.0f, 0.0f);
spring_max = ImVec2(rect_min.x + width, rect_max.y);
spacing_min = ImVec2(rect_min.x + width, rect_min.y);
}
else
{
spacing = floorf(item_spacing.y);
width = rect_size.y - spacing;
origin = ImVec2(floorf(rect_min.x + (rect_max.x - rect_min.x) / 2), floorf(rect_min.y));
direction = ImVec2(0.0f, 1.0f);
spring_max = ImVec2(rect_max.x, rect_min.y + width);
spacing_min = ImVec2(rect_min.x, rect_min.y + width);
}

if (spring_weight <= 0.0f && spacing <= 0.0f)
return;

ImDrawList* draw_list = ImGui::GetWindowDrawList();

draw_list->PushClipRect(rect_min, rect_max, true);

draw_list->AddRectFilled(rect_min, spring_max, ImColor(80, 20, 80));
draw_list->AddRectFilled(spacing_min, rect_max, ImColor(80, 20, 20));

const float zig_zag_size = 3;
ImVec2 normal = ImVec2(-direction.y, direction.x);

draw_list->PathClear();
origin.x += 0.5f;
origin.y += 0.5f;
draw_list->PathLineTo(origin);
for (float x = zig_zag_size * 0.5f; x <= width; x += zig_zag_size)
{
ImVec2 p;
p.x = origin.x + direction.x * x + normal.x * zig_zag_size;
p.y = origin.y + direction.y * x + normal.y * zig_zag_size;
draw_list->PathLineTo(p);
normal = ImVec2(-normal.x, -normal.y);
}
draw_list->PathStroke(ImColor(255, 255, 255, 190), false, 1.0f);

draw_list->PopClipRect();
}
};

ImGui::Checkbox("Widget A", &widget_a); ImGui::SameLine();
ImGui::Checkbox("Widget B", &widget_b); ImGui::SameLine();
ImGui::Checkbox("Widget C", &widget_c);
ImGui::Checkbox("Spring A", &spring_a); ImGui::SameLine();
ImGui::Checkbox("Spring AB", &spring_ab); ImGui::SameLine();
ImGui::Checkbox("Spring BC", &spring_bc); ImGui::SameLine();
ImGui::Checkbox("Spring C", &spring_c);
ImGui::Checkbox("Horizontal", &horizontal); ImGui::SameLine();
ImGui::Checkbox("Minimize Width", &minimize_width); ImGui::SameLine();
ImGui::Checkbox("Minimize Height", &minimize_height);
ImGui::Checkbox("Draw Springs", &draw_springs); ImGui::SameLine();
ImGui::TextUnformatted(" "); ImGui::SameLine();
ImGui::ColorButton("- Spring", ImColor(80, 20, 80), ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoPicker); ImGui::SameLine();
ImGui::TextUnformatted("Spring"); ImGui::SameLine();
ImGui::TextUnformatted(" "); ImGui::SameLine();
ImGui::ColorButton("- Spacing", ImColor(80, 20, 20), ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoPicker); ImGui::SameLine();
ImGui::TextUnformatted("Item Spacing");
ImGui::DragFloat("Item Spacing", horizontal ? &item_spacing.x : &item_spacing.y, 0.1f, 0.0f, 50.0f);
ImGui::DragFloat("A & C Spring Weight", &a_c_spring_weight, 0.002f, 0.0f, 1.0f);
ImGui::DragFloat("AB Spring Weight", &ab_spring_weight, 0.002f, 0.0f, 1.0f);
if (ImGui::IsItemHovered()) ImGui::SetTooltip("BC Spring Weight = 1 - AB Spring Weight");
ImGui::DragFloat("Minor Axis Alignment", &alignment, 0.002f, 0.0f, 1.0f);
if (ImGui::IsItemHovered()) ImGui::SetTooltip("This is vertical alignment for horizontal layouts and horizontal alignment for vertical layouts.");
ImGui::Text("Layout widgets:");
ImGui::Text("| Spring A | Widget A | Spring AB | Widget B | Spring BC | Widget C | Spring C |");

ImGui::Spacing();

ImVec2 widget_size;
widget_size.x = floorf(ImGui::GetContentRegionAvail().x / 4);
widget_size.y = horizontal ? floorf(widget_size.x / 3) : widget_size.x;

ImVec2 small_widget_size = widget_size;
if (horizontal)
small_widget_size.y = floorf(small_widget_size.y / 2);
else
small_widget_size.x = floorf(small_widget_size.x / 2);

ImVec2 layout_size = ImVec2(widget_size.x * 4, widget_size.y * 4);
if (minimize_width) layout_size.x = 0.0f;
if (minimize_height) layout_size.y = 0.0f;

// Minor axis alignment can be set by style or directly in BeginHorizontal/BeginVertical
// Example:
// ImGui::PushStyleVar(ImGuiStyleVar_LayoutAlign, alignment);

ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(floorf(item_spacing.x), floorf(item_spacing.y)));

if (horizontal) { ImGui::BeginHorizontal("h1", layout_size, alignment); } else { ImGui::BeginVertical("v1", layout_size, alignment); }
if (spring_a) { funcs::VisibleSpring(a_c_spring_weight); }
if (widget_a) { ImGui::Button("Widget A", widget_size); }
if (spring_ab) { funcs::VisibleSpring(ab_spring_weight); }
if (widget_b) { ImGui::Button("Widget B", small_widget_size); }
if (spring_bc) { funcs::VisibleSpring(1.0f - ab_spring_weight); }
if (widget_c) { ImGui::Button("Widget C", widget_size); }
if (spring_c) { funcs::VisibleSpring(a_c_spring_weight); }
if (horizontal) { ImGui::EndHorizontal(); } else { ImGui::EndVertical(); }

ImGui::PopStyleVar();

ImDrawList* draw_list = ImGui::GetWindowDrawList();
draw_list->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), ImGui::GetColorU32(ImGuiCol_Border));

ImGui::TreePop();
}
#endif // IMGUI_HAS_STACK_LAYOUT
}

static void ShowDemoWindowPopups()
Expand Down
9 changes: 9 additions & 0 deletions imgui_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Index of this file:
// [SECTION] Forward declarations
// [SECTION] Context pointer
// [SECTION] STB libraries includes
// [SECTION] Stack Layout includes
// [SECTION] Macros
// [SECTION] Generic helpers
// [SECTION] ImDrawList support
Expand Down Expand Up @@ -207,6 +208,14 @@ namespace ImStb

} // namespace ImStb

//-------------------------------------------------------------------------
// [SECTION] Stack Layout includes
//-------------------------------------------------------------------------

#if IMGUI_HAS_STACK_LAYOUT
# include "imgui_stacklayout_internal.h"
#endif

//-----------------------------------------------------------------------------
// [SECTION] Macros
//-----------------------------------------------------------------------------
Expand Down
Loading