@@ -3579,6 +3579,156 @@ static void ShowDemoWindowLayout()
35793579
35803580 ImGui::TreePop ();
35813581 }
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
35823732}
35833733
35843734static void ShowDemoWindowPopups ()
0 commit comments