general spec of location? if (submorph.isEpimorph) return; this.layout(supermorph); this.adjustShapeBoundsToSubmorphBounds(supermorph) }, afterRemoveMorph: function($super, supermorph, submorph) { if (submorph.isEpimorph) return; this.layout(supermorph); this.adjustShapeBoundsToSubmorphBounds(supermorph) supermorph.layoutChanged(); }, submorphExtentChanged: function(supermorph, submorph) { if (submorph.isEpimorph) return; var newExtent = submorph.getExtent(); var cachedExtent = this.getCachedExtent(supermorph, submorph) if (!cachedExtent || !(cachedExtent.eqPt(newExtent))) { this.setCachedExtent(supermorph, submorph, newExtent) this.layout(supermorph); this.adjustShapeBoundsToSubmorphBounds(supermorph); } }, layout: function($super, supermorph, submorph) { // console.log('full layout ' + supermorph.id()); // logStack(); $super(supermorph, submorph) } } VerticalLayout.subclass('VerticalShrinkLayout', ShrinkTrait); Object.extend(VerticalShrinkLayout, { fromLiteral: function(literal) { return new this() } }) HorizontalLayout.subclass('HorizontalShrinkLayout', ShrinkTrait) Object.extend(HorizontalShrinkLayout, { fromLiteral: function(literal) { return new this() } }) // splitArrayIntoPiecesOfLength([1,2,3,4,5,6,7], 3) -> [[1, 2, 3], [4, 5, 6], [7]] splitArrayIntoPiecesOfLength = function(array, n) { return array.inject([[]], function(a, ea) { var last = a.last() if(last.length == n) { last = []; a.push(last) } last.push(ea) return a }) } BoxMorph.subclass("ShrinkBoxMorph", { layoutManager: new HorizontalShrinkLayout(), style: {fill: Color.white, fillOpacity: 0}, layoutChanged: function($super) { $super(); if (this.owner && this.owner.submorphExtentChanged) this.owner.submorphExtentChanged(this); }, submorphExtentChanged: function(submorph) { if (this.layoutManager && this.layoutManager.submorphExtentChanged) this.layoutManager.submorphExtentChanged(this, submorph) }, }) ShrinkBoxMorph.subclass("ResourceNodeMorph", { defaultExtent: pt(120,40), padding: new Rectangle(5,5,0,0), margin: new Rectangle(5,3,0,0), initialize: function($super, url, optPosition, optLevel) { var pos = optPosition || pt(0,0); $super(pos.extent(this.defaultExtent)) this.setFill(Color.blue.darker()); this.setFillOpacity(0.3) this.setBorderColor(Color.darkGray) this.label = new TextMorph(new Rectangle(0,0,100,20)).beLabel(); this.addMorph(this.label) this.url = url this.setupConnections() this.layoutManager = new VerticalShrinkLayout(); }, setupConnections: function() { connect(this, "url", this.label, 'setTextString', {converter: function(value) { if (value instanceof URL) return value.filename() else return "no valid url" }}).update(this.url) }, expand: function(depth, level) { if (depth === 0) return; if (depth === undefined) depth = 1; if (!this.url) return; var children = new WebResource(this.url).getSubElements(1).subCollections children.each(function(ea) { var m = new ResourceNodeMorph(ea.getURL(), undefined ,this.level + 1); m.expand(depth - 1) this.addMorph(m) }, this) var leafChildren = new WebResource(this.url).getSubElements(1).subDocuments var leafChildrenRows = splitArrayIntoPiecesOfLength(leafChildren, 4); leafChildrenRows.each(function(eaRow) { var rowMorph = new ShrinkBoxMorph(); eaRow.each(function(ea) { var m = new ResourceNodeMorph(ea.getURL(), undefined , this.level + 1); m.submorphExtentChanged(m.label) rowMorph.addMorph(m) }, this); this.addMorph(rowMorph) }, this); }, }) ]]> Lively Kernel canvas