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.PositiveLengthStyleGrammar,
   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) {
     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(null, 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;

     this.markAsLaidOut();
     return {
       width: width,
       height: height,
     }
   }
   function layoutDescendants() {
     this.layout(node.width, node.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>
