From 93831ef456c872303350eb4cbd76e1c2be418c45 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 18 Jan 2021 18:02:23 +0100 Subject: [PATCH] LibWeb: Very basic support for CSS flex-direction The FFC now supports both vertical and horizontal flex layout, based on the flex-direction property. It's still extremely naive, but at least now you can be naive in two directions! :^) This implementation of flexbox is going to take a lot of work, but at least now we've gotten started. --- .../LibWeb/Layout/FlexFormattingContext.cpp | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index e9ebb54dc0..b67b6fa65c 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -41,22 +41,45 @@ FlexFormattingContext::~FlexFormattingContext() void FlexFormattingContext::run(Box& box, LayoutMode layout_mode) { - // FIXME: This is *extremely* naive and only supports flex items laid out on a single horizontal line. + // FIXME: This is *extremely* naive and only supports flex items laid out on a single line. - // First, compute the width of each flex item. + auto flex_direction = box.computed_values().flex_direction(); + bool horizontal = flex_direction == CSS::FlexDirection::Row || flex_direction == CSS::FlexDirection::RowReverse; + + auto available_width = box.containing_block()->width(); + + // First, compute the size of each flex item. box.for_each_child_of_type([&](Box& child_box) { auto shrink_to_fit_result = calculate_shrink_to_fit_widths(child_box); - auto shrink_to_fit_width = min(max(shrink_to_fit_result.preferred_minimum_width, 0.0f), shrink_to_fit_result.preferred_width); - layout_inside(child_box, layout_mode); + auto shrink_to_fit_width = min(max(shrink_to_fit_result.preferred_minimum_width, available_width), shrink_to_fit_result.preferred_width); child_box.set_width(shrink_to_fit_width); + layout_inside(child_box, layout_mode); }); - // Then, place the items on a line. + // Then, place the items on a vertical or horizontal line. float x = 0; + float y = 0; + float tallest_child_height = 0; + float widest_child_width = 0; box.for_each_child_of_type([&](Box& child_box) { - child_box.set_offset(x, 0); - x += child_box.border_box_width(); + child_box.set_offset(x, y); + tallest_child_height = max(tallest_child_height, child_box.height()); + widest_child_width = max(widest_child_width, child_box.width()); + if (horizontal) + x += child_box.margin_box_width(); + else + y += child_box.margin_box_height(); }); + + // Then, compute the height of the entire flex container. + // FIXME: This is not correct height calculation.. + if (horizontal) { + box.set_height(tallest_child_height); + box.set_width(x); + } else { + box.set_width(widest_child_width); + box.set_height(y); + } } }