SKY MODULE
<import src="sky:core" as="sky"/>
<script>
 // display: toolbar;
 // toolbar-spacing: <length>
 // display: spring; // remaining space is split equally amongst the springs
 // children are vertically centered, layout out left-to-right with toolbar-spacing space between them
 // last child is hidden by default unless there's not enough room for the others, then it's shown last, right-aligned
 module.exports.SpringLayoutManager = class SpringLayoutManager extends sky.LayoutManager { }
 sky.registerLayoutManager('spring', module.exports.SpringLayoutManager);
 sky.registerProperty({
   name: 'toolbar-spacing',
   type: sky.PositiveLengthStyleValueType,
   inherits: true,
   initialValue: 8,
   needsLayout: true,
 });
 module.exports.ToolbarLayoutManager = class ToolbarLayoutManager extends sky.LayoutManager {
   constructor (styleNode) {
     super(styleNode);
     this.showingOverflow = false;
     this.firstSkippedChild = null;
     this.overflowChild = null;
   }
   function layout(width, height) {
     this.markAsLaidOut();
     let children = null;
     let loop = null;
     if (height == null)
       height = this.getIntrinsicHeight().value;
     if (width == null)
       this.assumeDimensions(0, height);
     else
       this.assumeDimensions(width, height);
     let spacing = this.node.getProperty('toolbar-spacing');
     if (typeof spacing != 'number')
       spacing = 0;
     this.overflowChild = null;
     this.firstSkippedChild = null;

     // layout children and figure out whether we need to truncate the child list and show the overflow child
     let springCount = 0;
     let minX = 0;
     let overflowChildWidth = 0;
     let pendingSpacing = 0;
     children = this.walkChildren();
     loop = children.next();
     while (!loop.done) {
       let child = loop.value;
       let dims = null;
       if (child.layoutManager instanceof module.exports.SpringLayoutManager) {
         springCount += 1;
         pendingSpacing = spacing; // not +=, because we only have one extra spacing per batch of springs
       } else {
         if (child.needsLayout || child.descendantNeedsLayout) {
           childHeight = child.layoutManager.getIntrinsicHeight();
           if (childHeight.value < height)
             childHeight = childHeight.value;
           else
             childHeight = height;
           dims = child.layoutManager.layout(width, height);
           this.setChildSize(child, dims.width, dims.height);
         } else {
           dims = {
             width: child.width,
             height: child.height,
           };
         }
         loop = children.next();
         if (!loop.done) {
           if (minX > 0)
             minX += spacing + pendingSpacing;
           minX += dims.width;
           pendingSpacing = 0;
         } else {
           overflowChildWidth = spacing + dims.width;
           this.overflowChild = child;
         }
       }
     }

     // figure out the spacing
     this.showingOverflow = false;
     let springSize = 0;
     if (width != null) {
       if (minX <= width) {
         if (springCount > 0)
           springSize = (width - minX) / sprintCount;
       } else {
         this.showingOverflow = true;
       }
     } else {
       width = minX;
     }

     // position the children
     // TODO(ianh): support rtl toolbars
     let x = 0;
     let lastWasNonSpring = false;
     children = this.walkChildren();
     loop = children.next();
     while (!loop.done) {
       let child = loop.value;
       if (child.layoutManager instanceof module.exports.SpringLayoutManager) {
         x += springSize;
         if (lastWasNonSpring)
           x += spacing;
         lastWasNonSpring = false;
       } else {
         if (!loop.done) {
           if (x + child.width + overflowChildWidth > width) {
             this.firstSkippedChild = child;
             break; // don't display any more children
           }
           this.setChildPosition(child, x, (height - child.height)/2);
           x += child.width + spacing;
           lastWasNonSpring = true;
         } else {
           // assert: this.showingOverflow == false
         }
       }
     }
     if (this.showingOverflow)
       this.setChildPosition(this.overflowChild, width-this.overflowChild.width, (height - this.overflowChild.height)/2);
     else
       this.firstSkippedChild = this.overflowChild;

     return {
       width: width,
       height: height,
     }
   }
   function getIntrinsicWidth() {
     let width = this.node.getProperty('width');
     if (typeof width != 'number') {
       let spacing = this.node.getProperty('toolbar-spacing');
       if (typeof spacing != 'number')
         spacing = 0;
       width = 0;
       let children = this.walkChildren();
       let loop = children.next();
       // we exclude the last child because at our ideal width we wouldn't need it
       let last1 = null; // last one
       let last2 = null; // one before the last one
       while (!loop.done) {
         if (last1)
           width += last1.layoutManager.getIntrinsicWidth().value;
         if (last2)
           width += spacing;
         last2 = last1;
         last1 = loop.value;
         loop = children.next();
       }
     }
     return super(width); // applies and provides our own min-width/max-width rules
   }
   function getIntrinsicHeight() {
     // we grow our minimum height to be no smaller than the children's
     let result = super();
     let determineHeight = false;
     let heightProperty = this.node.getProperty('height');
     if (typeof heightProperty != 'number')
       determineHeight = true;
     let children = this.walkChildren();
     let loop = children.next();
     // here we include the last child so that if it pops in our height doesn't change
     while (!loop.done) {
       let child = loop.value;
       let childHeight = child.layoutManager.getIntrinsicHeight();
       if (determineHeight) {
         if (result.value < childHeight.value)
           result.value = childHeight.value;
       }
       if (result.minimum < childHeight.minimum)
         result.minimum = childHeight.minimum;
       loop = children.next();
     }
     if (result.minimum > result.maximum)
       result.maximum = result.minimum;
     if (result.value > result.maximum)
       result.value = result.maximum;
     if (result.value < result.minimum)
       result.value = result.minimum;
     return result;
   }
   function paintChildren(canvas) {
     let width = this.node.width;
     let children = this.walkChildren();
     let loop = children.next();
     while ((!loop.done) && (loop.value != this.firstSkippedChild))
       canvas.paintChild(loop.value);
     if (this.showingOverflow)
       canvas.paintChild(this.overflowChild);
   }
   function inChild(child, x, y) {
     return (x >= child.x) && (y >= child.y) && (x < child.x+child.width) && (y < child.y+child.height);
   }
   function hitTest(x, y) {
     let children = this.walkChildrenBackwards();
     let loop = children.next();
     while ((!loop.done) && (loop.value != this.firstSkippedChild))
       if (this.inChild(loop.value, x, y))
         return loop.value;
     if (this.showingOverflow)
       if (this.inChild(this.overflowChild, x, y))
         return this.overflowChild;
     return this.node;
   }
 }
 sky.registerLayoutManager('toolbar', module.exports.ToolbarLayoutManager);
</script>
