lullaby/modules/layout/layout.cc
// Calculate the secondary direction weight and sizes.
// Each iteration will either succeed by assigning a size to the weight
// increment that works, or remove a weight from a inner_group row and
// restart.  Eventually there will be no weights and it terminates, or it
// works meaning that the assigned size based on weight is greater than or
// equal to any fixed size elements in that row.
Calculate the secondary direction weight and sizes.
Each iteration will either succeed by assigning a size to the weight
increment that works, or remove a weight from a inner_group row and
restart.  Eventually there will be no weights and it terminates, or it
works meaning that the assigned size based on weight is greater than or
equal to any fixed size elements in that row.
Calculate the secondary direction weight and sizes . Each iteration will either succeed by assigning a size to the weight increment that works or remove a weight from a inner_group row and restart . Eventually there will be no weights and it terminates or it works meaning that the assigned size based on weight is greater than or equal to any fixed size elements in that row .
void ApplyLayoutOuterDesired(const float outer_spacing,
                             const float outer_canvas_size,
                             ApplyLayoutContext* context,
                             std::vector<OuterElement>* outer_elements) {
  for (size_t iter = 0; iter <= outer_elements->size(); ++iter) {
    if (iter == outer_elements->size()) {
      LOG(DFATAL) << "Exceeded maximum iterations for resizing outer elements: "
                  << outer_elements->size();
      break;
    }
    float total_outer_weight = 0.0f;
    float used_outer_size = 0.0f;
    for (size_t outer_idx = 0; outer_idx < outer_elements->size();
         ++outer_idx) {
      OuterElement& outer_element = outer_elements->at(outer_idx);
      UpdateWeightAndSize(outer_element.GetWeight(), outer_element.GetSize(),
                          &total_outer_weight, &used_outer_size);
    }
    if (total_outer_weight == 0) {
      break;
    }
    const float free_outer_size_per_weight = CalculateFreeSizePerWeight(
        used_outer_size, total_outer_weight, outer_spacing, outer_canvas_size,
        outer_elements->size());
    bool undersized = false;
    bool more_weight = false;
    for (size_t outer_idx = 0; outer_idx < outer_elements->size();
         ++outer_idx) {
      OuterElement& outer_element = outer_elements->at(outer_idx);
      if (outer_element.GetWeight() > 0) {
        const float child_outer_size = CalculateChildSizeFromWeight(
            outer_element.GetWeight(), free_outer_size_per_weight);
        if (child_outer_size < outer_element.GetSize()) {
          outer_element.SetWeight(0.0f);
          outer_element.SetWeightedSize(outer_element.GetSize());
          undersized = true;
        } else {
          outer_element.SetWeightedSize(child_outer_size);
          more_weight = true;
        }
      }
    }
    if (!undersized) {
      break;
    }
    if (!more_weight) {
      break;
    }
  }
  for (size_t outer_idx = 0; outer_idx < outer_elements->size(); ++outer_idx) {
    const InnerIndexRange range = context->GetRangeForOuter(outer_idx);
    if (range.size == 0) {
      continue;
    }
    OuterElement& outer_element = outer_elements->at(outer_idx);
    bool any_showing = false;
    for (size_t i = 0; i < range.size; ++i) {
      InnerElement inner_element = context->GetInnerElementInRange(range, i);
      if (inner_element.GetOuterWeight() > 0) {
        const float desired_size = outer_element.GetDesiredSize();
        inner_element.SetOuterDesiredSize(desired_size);
        if (desired_size > 0) {
          any_showing = true;
        }
      } else {
        any_showing = true;  
      }
    }
    outer_element.SetAllHiddenByWeight(!any_showing);
  }
}
void ApplyLayoutOuterDesired ( const float outer_spacing , const float outer_canvas_size , ApplyLayoutContext * context , std :: vector < OuterElement > * outer_elements ) { for ( size_t iter = 0 ; iter <= outer_elements -> size ( ) ; ++ iter ) { if ( iter == outer_elements -> size ( ) ) { LOG ( DFATAL ) << " " << outer_elements -> size ( ) ; break ; } float total_outer_weight = 0.0f ; float used_outer_size = 0.0f ; for ( size_t outer_idx = 0 ; outer_idx < outer_elements -> size ( ) ; ++ outer_idx ) { OuterElement & outer_element = outer_elements -> at ( outer_idx ) ; UpdateWeightAndSize ( outer_element . GetWeight ( ) , outer_element . GetSize ( ) , & total_outer_weight , & used_outer_size ) ; } if ( total_outer_weight == 0 ) { break ; } const float free_outer_size_per_weight = CalculateFreeSizePerWeight ( used_outer_size , total_outer_weight , outer_spacing , outer_canvas_size , outer_elements -> size ( ) ) ; bool undersized = false ; bool more_weight = false ; for ( size_t outer_idx = 0 ; outer_idx < outer_elements -> size ( ) ; ++ outer_idx ) { OuterElement & outer_element = outer_elements -> at ( outer_idx ) ; if ( outer_element . GetWeight ( ) > 0 ) { const float child_outer_size = CalculateChildSizeFromWeight ( outer_element . GetWeight ( ) , free_outer_size_per_weight ) ; if ( child_outer_size < outer_element . GetSize ( ) ) { outer_element . SetWeight ( 0.0f ) ; outer_element . SetWeightedSize ( outer_element . GetSize ( ) ) ; undersized = true ; } else { outer_element . SetWeightedSize ( child_outer_size ) ; more_weight = true ; } } } if ( ! undersized ) { break ; } if ( ! more_weight ) { break ; } } for ( size_t outer_idx = 0 ; outer_idx < outer_elements -> size ( ) ; ++ outer_idx ) { const InnerIndexRange range = context -> GetRangeForOuter ( outer_idx ) ; if ( range . size == 0 ) { continue ; } OuterElement & outer_element = outer_elements -> at ( outer_idx ) ; bool any_showing = false ; for ( size_t i = 0 ; i < range . size ; ++ i ) { InnerElement inner_element = context -> GetInnerElementInRange ( range , i ) ; if ( inner_element . GetOuterWeight ( ) > 0 ) { const float desired_size = outer_element . GetDesiredSize ( ) ; inner_element . SetOuterDesiredSize ( desired_size ) ; if ( desired_size > 0 ) { any_showing = true ; } } else { any_showing = true ; } } outer_element . SetAllHiddenByWeight ( ! any_showing ) ; } }
Calculate the secondary direction weight and sizes.
Calculate the secondary direction weight and sizes .
// There should be at most one iteration per element, since each iteration // will remove the weight from at least one element if it doesnt exit. // There is no weight to calculate, done. // Check that the calculated size is greater than or equal to any // fixed size.  If any aren't, ignore those weights and restart. // But, only restart if there is more weight to calculate anyway. // Don't use weight, just leave as original max_size. // No children are undersized, we are done. // There is no more weight to process, we are done. // Some children are undersized and there is more weight left, so restart // with some weight removed. // Now go and update all weighted children with their calculated size. // Note that any weighted children in the same row will get the same size, // based on max_weight, no matter their original weight because they'll // just fill available space. // Also, if max_size is greater, use that instead. // If any are showing, then the row is not all_hidden_by_weight. // Apply weighted size to any element with outer_weight. // If no weight it counts as showing. // If are none showing, then the row is all_hidden_by_weight. // We successfully allocated sizes to weighted children, done.