| OLD | NEW |
| 1 #!mojo mojo:sky | 1 #!mojo mojo:sky |
| 2 <import src="sky:core" as="sky"/> | 2 <import src="sky:core" as="sky"/> |
| 3 <script> | 3 <script> |
| 4 class BeehiveLayoutManager extends sky.LayoutManager { | 4 class BeehiveLayoutManager extends sky.LayoutManager { |
| 5 function layout(width, height) { | 5 function layout(width, height) { |
| 6 this.markAsLaidOut(); | 6 this.markAsLaidOut(); |
| 7 if (width == null) | 7 if (width == null) |
| 8 width = this.getIntrinsicWidth().value; | 8 width = this.getIntrinsicWidth().value; |
| 9 let autoHeight = false; | 9 let autoHeight = false; |
| 10 if (height == null) { | 10 if (height == null) { |
| 11 height = 0; | 11 height = 0; |
| 12 autoHeight = true; | 12 autoHeight = true; |
| 13 } | 13 } |
| 14 this.assumeDimensions(width, height); | 14 this.assumeDimensions(width, height); |
| 15 let cellCount = this.node.getProperty('beehive-count'); | 15 let cellCount = this.node.getProperty('beehive-count'); |
| 16 let cellDim = width / cellCount; | 16 let cellDim = width / cellCount; |
| 17 let children = this.walkChildren(); | 17 let children = this.walkChildren(); |
| 18 let loop = children.next(); | 18 let loop = children.next(); |
| 19 let x = 0; | 19 let x = 0; |
| 20 let y = 0; | 20 let y = 0; |
| 21 while (!loop.done) { | 21 while (!loop.done) { |
| 22 let child = loop.value; | 22 let child = loop.value; |
| 23 if (child.needsLayout) { | 23 if (child.needsLayout || child.descendantNeedsLayout) { |
| 24 child.layoutManager.layout(cellDim, cellDim); | 24 child.layoutManager.layout(cellDim, cellDim); |
| 25 // we ignore the size the child reported from layout(), and force it to
the cell dimensions | 25 // we ignore the size the child reported from layout(), and force it to
the cell dimensions |
| 26 this.setChildSize(child, cellDim, cellDim); | 26 this.setChildSize(child, cellDim, cellDim); |
| 27 } | 27 } |
| 28 this.setChildPosition(child, x * cellDim + (y % 2) * cellDim/2, y * 3/4 *
cellDim); | 28 this.setChildPosition(child, x * cellDim + (y % 2) * cellDim/2, y * 3/4 *
cellDim); |
| 29 x += 1; | 29 x += 1; |
| 30 if (x > cellCount) { | 30 if (x > cellCount) { |
| 31 y += 1; | 31 y += 1; |
| 32 x = 0; | 32 x = 0; |
| 33 } | 33 } |
| 34 loop = children.next(); | 34 loop = children.next(); |
| 35 } | 35 } |
| 36 if (height == 0) | 36 if (height == 0) |
| 37 height = (1 + y * 3/4) * cellDim; | 37 height = (1 + y * 3/4) * cellDim; |
| 38 return { | 38 return { |
| 39 width: width, | 39 width: width, |
| 40 height: height, | 40 height: height, |
| 41 } | 41 } |
| 42 } | 42 } |
| 43 function getIntrinsicWidth() { | |
| 44 // this is the logic that LayoutManager.getIntrinsicWidth() has by default | |
| 45 // shown here because I wrote it before realising it should be the default | |
| 46 let width = this.node.getProperty('width'); | |
| 47 if (typeof width != 'number') | |
| 48 width = 0; | |
| 49 let minWidth = this.node.getProperty('min-width'); | |
| 50 if (typeof width != 'number') | |
| 51 minWidth = 0; | |
| 52 let maxWidth = this.node.getProperty('max-width'); | |
| 53 if (typeof width != 'number') | |
| 54 maxWidth = Infinity; | |
| 55 if (maxWidth < minWidth) | |
| 56 maxWidth = minWidth; | |
| 57 if (width > maxWidth) | |
| 58 width = maxWidth; | |
| 59 if (width < minWidth) | |
| 60 width = minWidth; | |
| 61 return { | |
| 62 minimum: minWidth, | |
| 63 value: width, | |
| 64 maximum: maxWidth, | |
| 65 }; | |
| 66 } | |
| 67 function getIntrinsicHeight() { | 43 function getIntrinsicHeight() { |
| 68 let height = this.node.getProperty('height'); | 44 let height = this.node.getProperty('height'); |
| 69 if (typeof height != 'number') { | 45 if (typeof height != 'number') { |
| 70 // e.g. height: auto | 46 // e.g. height: auto |
| 71 width = this.getIntrinsicWidth().value; | 47 width = this.getIntrinsicWidth().value; |
| 72 let cellCount = this.node.getProperty('beehive-count'); | 48 let cellCount = this.node.getProperty('beehive-count'); |
| 73 let cellDim = width / cellCount; | 49 let cellDim = width / cellCount; |
| 74 let children = this.walkChildren(); | 50 let children = this.walkChildren(); |
| 75 let loop = children.next(); | 51 let loop = children.next(); |
| 76 let childCount = 0; | 52 let childCount = 0; |
| 77 while (!loop.done) { | 53 while (!loop.done) { |
| 78 childCount += 1; | 54 childCount += 1; |
| 79 loop.next(); | 55 loop.next(); |
| 80 } | 56 } |
| 81 if (childCount > 0) | 57 if (childCount > 0) |
| 82 height = cellDim * (1/4 + Math.ceil(childCount / cellCount) * 3/4); | 58 height = cellDim * (1/4 + Math.ceil(childCount / cellCount) * 3/4); |
| 83 else | 59 else |
| 84 height = 0; | 60 height = 0; |
| 85 } | 61 } |
| 86 return super(height); // does the equivalent of getIntrinsicWidth() above,
applying min-height etc | 62 return super(height); // does the equivalent of getIntrinsicWidth() above,
applying min-height etc |
| 87 } | 63 } |
| 88 function paintChildren(canvas) { | 64 function paintChildren(canvas) { |
| 89 let width = this.node.width; | 65 let width = this.node.width; |
| 90 let cellCount = this.node.getProperty('beehive-count'); | 66 let cellCount = this.node.getProperty('beehive-count'); |
| 91 let cellDim = width / cellCount; | 67 let cellDim = width / cellCount; |
| 92 let children = this.walkChildren(); | 68 let children = this.walkChildren(); |
| 93 let loop = children.next(); | 69 let loop = children.next(); |
| 94 while (!loop.done) { | 70 while (!loop.done) { |
| 95 let child = loop.value; | 71 let child = loop.value; |
| 96 if (child.needsPaint) { | 72 if (child.needsPaint || child.descendantNeedsPaint) { |
| 97 canvas.save(); | 73 canvas.save(); |
| 98 try { | 74 try { |
| 99 canvas.beginPath(); | 75 canvas.beginPath(); |
| 100 canvas.translate(child.x, child.y); | 76 canvas.moveTo(child.x, child.y + cellDim/4); |
| 101 canvas.moveTo(0, cellDim/4); | 77 canvas.lineTo(child.x + cellDim/2, child.y); |
| 102 canvas.lineTo(cellDim/2, 0); | 78 canvas.lineTo(child.x + cellDim, child.y + cellDim/4); |
| 103 canvas.lineTo(cellDim, cellDim/4); | 79 canvas.lineTo(child.x + cellDim, child.y + 3*cellDim/4); |
| 104 canvas.lineTo(cellDim, 3*cellDim/4); | 80 canvas.lineTo(child.x + cellDim/2, child.y + cellDim); |
| 105 canvas.lineTo(cellDim/2, cellDim); | 81 canvas.moveTo(child.x, child.y + 3*cellDim/4); |
| 106 canvas.moveTo(0, 3*cellDim/4); | |
| 107 canvas.closePath(); | 82 canvas.closePath(); |
| 108 canvas.clip(); | 83 canvas.clip(); |
| 109 child.paint(canvas); | 84 this.paintChild(child); |
| 110 } finally { | 85 } finally { |
| 111 canvas.restore(); | 86 canvas.restore(); |
| 112 } | 87 } |
| 113 } | 88 } |
| 114 loop = children.next(); | 89 loop = children.next(); |
| 115 } | 90 } |
| 116 } | 91 } |
| 117 function inHex(topLeftX, topLeftY, width, height, hitX, hitY) { | 92 function inHex(topLeftX, topLeftY, width, height, hitX, hitY) { |
| 118 let centerX = topLeftX - width/2; | 93 let centerX = topLeftX - width/2; |
| 119 let absCenteredHitX = Math.abs(hitX - centerX); | 94 let absCenteredHitX = Math.abs(hitX - centerX); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 div { display: beehive; beehive-count: 3; } | 144 div { display: beehive; beehive-count: 3; } |
| 170 </style> | 145 </style> |
| 171 <div> | 146 <div> |
| 172 <t>Hello</t> | 147 <t>Hello</t> |
| 173 <t>World</t> | 148 <t>World</t> |
| 174 <t>How</t> | 149 <t>How</t> |
| 175 <t>Are</t> | 150 <t>Are</t> |
| 176 <t>You</t> | 151 <t>You</t> |
| 177 <t>Today?</t> | 152 <t>Today?</t> |
| 178 </div> | 153 </div> |
| OLD | NEW |