@@ -3579,6 +3579,156 @@ static void ShowDemoWindowLayout()
3579
3579
3580
3580
ImGui::TreePop();
3581
3581
}
3582
+
3583
+ #if IMGUI_HAS_STACK_LAYOUT
3584
+ IMGUI_DEMO_MARKER("Layout/Stack Layout");
3585
+ if (ImGui::TreeNode("Stack Layout"))
3586
+ {
3587
+ static bool widget_a = true, widget_b = true, widget_c = true;
3588
+ static bool spring_a = true, spring_ab = true, spring_bc = true, spring_c = true;
3589
+ static bool minimize_width = false, minimize_height = true;
3590
+ static bool horizontal = true, draw_springs = true;
3591
+ static ImVec2 item_spacing = ImGui::GetStyle().ItemSpacing;
3592
+ static float a_c_spring_weight = 0.0f;
3593
+ static float ab_spring_weight = 0.5f;
3594
+ static float alignment = 0.5f;
3595
+
3596
+ struct funcs
3597
+ {
3598
+ static void VisibleSpring(float spring_weight)
3599
+ {
3600
+ ImGui::Spring(spring_weight);
3601
+ if (!draw_springs)
3602
+ return;
3603
+
3604
+ ImVec2 rect_min = ImGui::GetItemRectMin();
3605
+ ImVec2 rect_max = ImGui::GetItemRectMax();
3606
+
3607
+ ImVec2 rect_size = ImGui::GetItemRectSize();
3608
+ if (rect_size.x <= 0.0f && rect_size.y <= 0.0f)
3609
+ return;
3610
+
3611
+ // Draw zig-zag
3612
+ float width = 0.0f, spacing = 0.0f;
3613
+ ImVec2 direction, origin;
3614
+ ImVec2 spacing_min, spring_max;
3615
+
3616
+ if (horizontal)
3617
+ {
3618
+ spacing = floorf(item_spacing.x);
3619
+ width = rect_size.x - spacing;
3620
+ origin = ImVec2(floorf(rect_min.x), floorf(rect_min.y + (rect_max.y - rect_min.y) / 2));
3621
+ direction = ImVec2(1.0f, 0.0f);
3622
+ spring_max = ImVec2(rect_min.x + width, rect_max.y);
3623
+ spacing_min = ImVec2(rect_min.x + width, rect_min.y);
3624
+ }
3625
+ else
3626
+ {
3627
+ spacing = floorf(item_spacing.y);
3628
+ width = rect_size.y - spacing;
3629
+ origin = ImVec2(floorf(rect_min.x + (rect_max.x - rect_min.x) / 2), floorf(rect_min.y));
3630
+ direction = ImVec2(0.0f, 1.0f);
3631
+ spring_max = ImVec2(rect_max.x, rect_min.y + width);
3632
+ spacing_min = ImVec2(rect_min.x, rect_min.y + width);
3633
+ }
3634
+
3635
+ if (spring_weight <= 0.0f && spacing <= 0.0f)
3636
+ return;
3637
+
3638
+ ImDrawList* draw_list = ImGui::GetWindowDrawList();
3639
+
3640
+ draw_list->PushClipRect(rect_min, rect_max, true);
3641
+
3642
+ draw_list->AddRectFilled(rect_min, spring_max, ImColor(80, 20, 80));
3643
+ draw_list->AddRectFilled(spacing_min, rect_max, ImColor(80, 20, 20));
3644
+
3645
+ const float zig_zag_size = 3;
3646
+ ImVec2 normal = ImVec2(-direction.y, direction.x);
3647
+
3648
+ draw_list->PathClear();
3649
+ origin.x += 0.5f;
3650
+ origin.y += 0.5f;
3651
+ draw_list->PathLineTo(origin);
3652
+ for (float x = zig_zag_size * 0.5f; x <= width; x += zig_zag_size)
3653
+ {
3654
+ ImVec2 p;
3655
+ p.x = origin.x + direction.x * x + normal.x * zig_zag_size;
3656
+ p.y = origin.y + direction.y * x + normal.y * zig_zag_size;
3657
+ draw_list->PathLineTo(p);
3658
+ normal = ImVec2(-normal.x, -normal.y);
3659
+ }
3660
+ draw_list->PathStroke(ImColor(255, 255, 255, 190), false, 1.0f);
3661
+
3662
+ draw_list->PopClipRect();
3663
+ }
3664
+ };
3665
+
3666
+ ImGui::Checkbox("Widget A", &widget_a); ImGui::SameLine();
3667
+ ImGui::Checkbox("Widget B", &widget_b); ImGui::SameLine();
3668
+ ImGui::Checkbox("Widget C", &widget_c);
3669
+ ImGui::Checkbox("Spring A", &spring_a); ImGui::SameLine();
3670
+ ImGui::Checkbox("Spring AB", &spring_ab); ImGui::SameLine();
3671
+ ImGui::Checkbox("Spring BC", &spring_bc); ImGui::SameLine();
3672
+ ImGui::Checkbox("Spring C", &spring_c);
3673
+ ImGui::Checkbox("Horizontal", &horizontal); ImGui::SameLine();
3674
+ ImGui::Checkbox("Minimize Width", &minimize_width); ImGui::SameLine();
3675
+ ImGui::Checkbox("Minimize Height", &minimize_height);
3676
+ ImGui::Checkbox("Draw Springs", &draw_springs); ImGui::SameLine();
3677
+ ImGui::TextUnformatted(" "); ImGui::SameLine();
3678
+ ImGui::ColorButton("- Spring", ImColor(80, 20, 80), ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoPicker); ImGui::SameLine();
3679
+ ImGui::TextUnformatted("Spring"); ImGui::SameLine();
3680
+ ImGui::TextUnformatted(" "); ImGui::SameLine();
3681
+ ImGui::ColorButton("- Spacing", ImColor(80, 20, 20), ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoPicker); ImGui::SameLine();
3682
+ ImGui::TextUnformatted("Item Spacing");
3683
+ ImGui::DragFloat("Item Spacing", horizontal ? &item_spacing.x : &item_spacing.y, 0.1f, 0.0f, 50.0f);
3684
+ ImGui::DragFloat("A & C Spring Weight", &a_c_spring_weight, 0.002f, 0.0f, 1.0f);
3685
+ ImGui::DragFloat("AB Spring Weight", &ab_spring_weight, 0.002f, 0.0f, 1.0f);
3686
+ if (ImGui::IsItemHovered()) ImGui::SetTooltip("BC Spring Weight = 1 - AB Spring Weight");
3687
+ ImGui::DragFloat("Minor Axis Alignment", &alignment, 0.002f, 0.0f, 1.0f);
3688
+ if (ImGui::IsItemHovered()) ImGui::SetTooltip("This is vertical alignment for horizontal layouts and horizontal alignment for vertical layouts.");
3689
+ ImGui::Text("Layout widgets:");
3690
+ ImGui::Text("| Spring A | Widget A | Spring AB | Widget B | Spring BC | Widget C | Spring C |");
3691
+
3692
+ ImGui::Spacing();
3693
+
3694
+ ImVec2 widget_size;
3695
+ widget_size.x = floorf(ImGui::GetContentRegionAvail().x / 4);
3696
+ widget_size.y = horizontal ? floorf(widget_size.x / 3) : widget_size.x;
3697
+
3698
+ ImVec2 small_widget_size = widget_size;
3699
+ if (horizontal)
3700
+ small_widget_size.y = floorf(small_widget_size.y / 2);
3701
+ else
3702
+ small_widget_size.x = floorf(small_widget_size.x / 2);
3703
+
3704
+ ImVec2 layout_size = ImVec2(widget_size.x * 4, widget_size.y * 4);
3705
+ if (minimize_width) layout_size.x = 0.0f;
3706
+ if (minimize_height) layout_size.y = 0.0f;
3707
+
3708
+ // Minor axis alignment can be set by style or directly in BeginHorizontal/BeginVertical
3709
+ // Example:
3710
+ // ImGui::PushStyleVar(ImGuiStyleVar_LayoutAlign, alignment);
3711
+
3712
+ ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(floorf(item_spacing.x), floorf(item_spacing.y)));
3713
+
3714
+ if (horizontal) { ImGui::BeginHorizontal("h1", layout_size, alignment); } else { ImGui::BeginVertical("v1", layout_size, alignment); }
3715
+ if (spring_a) { funcs::VisibleSpring(a_c_spring_weight); }
3716
+ if (widget_a) { ImGui::Button("Widget A", widget_size); }
3717
+ if (spring_ab) { funcs::VisibleSpring(ab_spring_weight); }
3718
+ if (widget_b) { ImGui::Button("Widget B", small_widget_size); }
3719
+ if (spring_bc) { funcs::VisibleSpring(1.0f - ab_spring_weight); }
3720
+ if (widget_c) { ImGui::Button("Widget C", widget_size); }
3721
+ if (spring_c) { funcs::VisibleSpring(a_c_spring_weight); }
3722
+ if (horizontal) { ImGui::EndHorizontal(); } else { ImGui::EndVertical(); }
3723
+
3724
+ ImGui::PopStyleVar();
3725
+
3726
+ ImDrawList* draw_list = ImGui::GetWindowDrawList();
3727
+ draw_list->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), ImGui::GetColorU32(ImGuiCol_Border));
3728
+
3729
+ ImGui::TreePop();
3730
+ }
3731
+ #endif // IMGUI_HAS_STACK_LAYOUT
3582
3732
}
3583
3733
3584
3734
static void ShowDemoWindowPopups()
0 commit comments