lullaby/contrib/layout/layout_system.cc
// When the parameters for determining a Layout change, e.g.
// OriginalBoxChanged, ParentChangedEvent, or any change in LayoutParams, then
// the Layout will set its original_size and its children's desired_size.
// When it is setting original_size it use its original canvas_size.
//
// OnDesiredSizeChanged, it does not set its original_size, only actual_size.
// When it sets actual_size it uses its assigned desired_size if previously set.
//
// OnActualBoxChanged, it does not set its original_size or any children's
// desired_size.
// However, if it is the source of an ActualBoxChangedEvent, it will
// SetOriginal instead of SetActual, since that event was a result of one of
// its previous kOriginal passes, but still won't set any children's
// desired_size.
When the parameters for determining a Layout change, e.g.
OriginalBoxChanged, ParentChangedEvent, or any change in LayoutParams, then
the Layout will set its original_size and its children's desired_size.
When it is setting original_size it use its original canvas_size.



OnActualBoxChanged, it does not set its original_size or any children's
desired_size.
However, if it is the source of an ActualBoxChangedEvent, it will
SetOriginal instead of SetActual, since that event was a result of one of
its previous kOriginal passes, but still won't set any children's
desired_size.
When the parameters for determining a Layout change e . g . OriginalBoxChanged ParentChangedEvent or any change in LayoutParams then the Layout will set its original_size and its children ' s desired_size . When it is setting original_size it use its original canvas_size . OnActualBoxChanged it does not set its original_size or any children ' s desired_size . However if it is the source of an ActualBoxChangedEvent it will SetOriginal instead of SetActual since that event was a result of one of its previous kOriginal passes but still won ' t set any children ' s desired_size .
void LayoutSystem::LayoutImpl(const DirtyLayout& dirty_layout) {
  const Entity e = dirty_layout.GetLayout();
  LayoutComponent* layout = layouts_.Get(e);
  auto* transform_system = registry_->Get<TransformSystem>();
  if (layout == nullptr) {
    return;
  }
  const std::vector<Entity>* children = transform_system->GetChildren(e);
  if (children == nullptr) {
    return;
  }
  auto* entity_factory = registry_->Get<EntityFactory>();
  if (!layout->empty_blueprint.empty()) {
    while (children->size() < layout->max_elements) {
      Entity empty_placeholder = transform_system->CreateChild(e,
          layout->empty_blueprint);
      if (empty_placeholder == kNullEntity) {
        LOG(WARNING) << "could not find blueprint and create placeholders";
        break;
      }
      layout->empty_placeholders.push(empty_placeholder);
    }
  }
  while (children->size() > layout->max_elements &&
         !layout->empty_placeholders.empty()) {
    entity_factory->Destroy(layout->empty_placeholders.front());
    layout->empty_placeholders.pop();
  }
  if (layout->max_elements > 0 && children->size() > layout->max_elements) {
    LOG(WARNING) << "layout " << e << " has more children than max_elements";
  }
  if (layout->layout) {
    std::vector<LayoutElement> elements;
    elements.reserve(children->size());
    for (const Entity& child : *children) {
      if (layout->ignore_mode == LayoutIgnoreMode_Disabled &&
          !transform_system->IsEnabled(child)) {
        continue;
      }
      if (ignored_layout_elements_.count(child) > 0) {
        continue;
      }
      elements.emplace_back(GetLayoutElement(child));
    }
    auto* layout_box_system = registry_->Get<LayoutBoxSystem>();
    LayoutParams params = *layout->layout;
    if (dirty_layout.ShouldUseDesiredSize()) {
      Optional<float> x = layout_box_system->GetDesiredSizeX(e);
      Optional<float> y = layout_box_system->GetDesiredSizeY(e);
      if (x) {
        params.canvas_size.x = *x;
      }
      if (y) {
        params.canvas_size.y = *y;
      }
    }
    const auto set_pos_fn = [this](Entity entity, const mathfu::vec2& pos) {
      SetLayoutPosition(entity, pos);
    };
    const Aabb aabb = ApplyLayout(registry_, params, elements, set_pos_fn,
                                  dirty_layout.GetChildrensDesiredSource(),
                                  &layout->cached_positions);
    transform_system->SetAabb(e, aabb);
    if (dirty_layout.ShouldSetActualBox()) {
      layout_box_system->SetActualBox(e, dirty_layout.GetActualSource(), aabb);
    } else {
      layout_box_system->SetOriginalBox(e, aabb);
    }
  } else if (layout->radial_layout) {
    ApplyRadialLayout(registry_, *children, *layout->radial_layout);
  } else {
    LOG(DFATAL) << "Cannot layout LayoutComponent with no layout parameters.";
    return;
  }
  SendEvent(registry_, e, LayoutChangedEvent(e));
}
void LayoutSystem :: LayoutImpl ( const DirtyLayout & dirty_layout ) { const Entity e = dirty_layout . GetLayout ( ) ; LayoutComponent * layout = layouts_ . Get ( e ) ; auto * transform_system = registry_ -> Get < TransformSystem > ( ) ; if ( layout == nullptr ) { return ; } const std :: vector < Entity > * children = transform_system -> GetChildren ( e ) ; if ( children == nullptr ) { return ; } auto * entity_factory = registry_ -> Get < EntityFactory > ( ) ; if ( ! layout -> empty_blueprint . empty ( ) ) { while ( children -> size ( ) < layout -> max_elements ) { Entity empty_placeholder = transform_system -> CreateChild ( e , layout -> empty_blueprint ) ; if ( empty_placeholder == kNullEntity ) { LOG ( WARNING ) << " " ; break ; } layout -> empty_placeholders . push ( empty_placeholder ) ; } } while ( children -> size ( ) > layout -> max_elements && ! layout -> empty_placeholders . empty ( ) ) { entity_factory -> Destroy ( layout -> empty_placeholders . front ( ) ) ; layout -> empty_placeholders . pop ( ) ; } if ( layout -> max_elements > 0 && children -> size ( ) > layout -> max_elements ) { LOG ( WARNING ) << " " << e << " " ; } if ( layout -> layout ) { std :: vector < LayoutElement > elements ; elements . reserve ( children -> size ( ) ) ; for ( const Entity & child : * children ) { if ( layout -> ignore_mode == LayoutIgnoreMode_Disabled && ! transform_system -> IsEnabled ( child ) ) { continue ; } if ( ignored_layout_elements_ . count ( child ) > 0 ) { continue ; } elements . emplace_back ( GetLayoutElement ( child ) ) ; } auto * layout_box_system = registry_ -> Get < LayoutBoxSystem > ( ) ; LayoutParams params = * layout -> layout ; if ( dirty_layout . ShouldUseDesiredSize ( ) ) { Optional < float > x = layout_box_system -> GetDesiredSizeX ( e ) ; Optional < float > y = layout_box_system -> GetDesiredSizeY ( e ) ; if ( x ) { params . canvas_size . x = * x ; } if ( y ) { params . canvas_size . y = * y ; } } const auto set_pos_fn = [ this ] ( Entity entity , const mathfu :: vec2 & pos ) { SetLayoutPosition ( entity , pos ) ; } ; const Aabb aabb = ApplyLayout ( registry_ , params , elements , set_pos_fn , dirty_layout . GetChildrensDesiredSource ( ) , & layout -> cached_positions ) ; transform_system -> SetAabb ( e , aabb ) ; if ( dirty_layout . ShouldSetActualBox ( ) ) { layout_box_system -> SetActualBox ( e , dirty_layout . GetActualSource ( ) , aabb ) ; } else { layout_box_system -> SetOriginalBox ( e , aabb ) ; } } else if ( layout -> radial_layout ) { ApplyRadialLayout ( registry_ , * children , * layout -> radial_layout ) ; } else { LOG ( DFATAL ) << " " ; return ; } SendEvent ( registry_ , e , LayoutChangedEvent ( e ) ) ; }
When the parameters for determining a Layout change, e.g.
When the parameters for determining a Layout change e . g .
// If needed, add empty placeholders to fill up the layout. // And, remove placeholders if they aren't needed anymore. // Use assigned desired_size if it has been set any time the original_size // is not calculated from scratch.