diff options
Diffstat (limited to 'html/lib/layout/fittable')
-rw-r--r-- | html/lib/layout/fittable/package.js | 3 | ||||
-rw-r--r-- | html/lib/layout/fittable/source/FittableColumns.js | 41 | ||||
-rw-r--r-- | html/lib/layout/fittable/source/FittableLayout.css | 69 | ||||
-rw-r--r-- | html/lib/layout/fittable/source/FittableLayout.js | 265 | ||||
-rw-r--r-- | html/lib/layout/fittable/source/FittableRows.js | 40 | ||||
-rw-r--r-- | html/lib/layout/fittable/source/design.js | 23 | ||||
-rw-r--r-- | html/lib/layout/fittable/source/package.js | 6 |
7 files changed, 447 insertions, 0 deletions
diff --git a/html/lib/layout/fittable/package.js b/html/lib/layout/fittable/package.js new file mode 100644 index 0000000..3fae95b --- /dev/null +++ b/html/lib/layout/fittable/package.js @@ -0,0 +1,3 @@ +enyo.depends( + "source" +);
\ No newline at end of file diff --git a/html/lib/layout/fittable/source/FittableColumns.js b/html/lib/layout/fittable/source/FittableColumns.js new file mode 100644 index 0000000..d28b6fe --- /dev/null +++ b/html/lib/layout/fittable/source/FittableColumns.js @@ -0,0 +1,41 @@ +/** + _enyo.FittableColumns_ provides a container in which items are laid out in a + set of vertical columns, with most items having natural size, but one + expanding to fill the remaining space. The one that expands is labeled with + the attribute _fit: true_. + + For example, the following code will align three components as columns, with + the second filling the available container space between the first and third: + + enyo.kind({ + kind: "FittableColumns", + components: [ + {content: "1"}, + {content: "2", fit:true}, + {content: "3"} + ] + }); + + Alternatively, you may set a kind's _layoutKind_ property to + <a href="#enyo.FittableColumnsLayout">enyo.FittableColumnsLayout</a> + to use a different base kind while still employing the fittable layout + strategy, e.g.: + + enyo.kind({ + kind: enyo.Control, + layoutKind: "FittableColumnsLayout", + components: [ + {content: "1"}, + {content: "2", fit:true}, + {content: "3"} + ] + }); +*/ + +enyo.kind({ + name: "enyo.FittableColumns", + layoutKind: "FittableColumnsLayout", + /** By default, items in columns stretch to fit vertically; set to true to + avoid this behavior. */ + noStretch: false +}); diff --git a/html/lib/layout/fittable/source/FittableLayout.css b/html/lib/layout/fittable/source/FittableLayout.css new file mode 100644 index 0000000..cdc24b8 --- /dev/null +++ b/html/lib/layout/fittable/source/FittableLayout.css @@ -0,0 +1,69 @@ +.enyo-fittable-rows-layout { + position: relative; +} + +.enyo-fittable-rows-layout > * { + box-sizing: border-box; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + /* float when not stretched */ + float: left; + clear: both; +} + +/* non-floating when stretched */ +.enyo-fittable-rows-layout.enyo-stretch > * { + float: none; + clear: none; +} + +/* setting to enforce margin collapsing */ +/* NOTE: rows cannot have margin left/right */ +.enyo-fittable-rows-layout.enyo-stretch.enyo-margin-expand > * { + float: left; + clear: both; + width: 100%; + /* note: harsh resets */ + margin-left: 0 !important; + margin-right: 0 !important; +} + +.enyo-fittable-columns-layout { + position: relative; + text-align: left; + white-space: nowrap; +} + +.enyo-fittable-columns-layout.enyo-center { + text-align: center; +} + +.enyo-fittable-columns-layout > * { + box-sizing: border-box; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + vertical-align: top; + display: inline-block; + white-space: normal; +} + +.enyo-fittable-columns-layout.enyo-tool-decorator > * { + vertical-align: middle; +} + +/* repair clobbered white-space setting for pre, code */ +.enyo-fittable-columns-layout > pre, .enyo-fittable-columns-layout > code { + white-space: pre; +} + +.enyo-fittable-columns-layout > .enyo-fittable-columns-layout, .enyo-fittable-columns-layout > .onyx-toolbar-inline { + white-space: nowrap; +} + +/* NOTE: columns cannot have margin top/bottom */ +.enyo-fittable-columns-layout.enyo-stretch > * { + height: 100%; + /* note: harsh resets */ + margin-top: 0 !important; + margin-bottom: 0 !important; +}
\ No newline at end of file diff --git a/html/lib/layout/fittable/source/FittableLayout.js b/html/lib/layout/fittable/source/FittableLayout.js new file mode 100644 index 0000000..6045e65 --- /dev/null +++ b/html/lib/layout/fittable/source/FittableLayout.js @@ -0,0 +1,265 @@ +/** + _enyo.FittableLayout_ provides the base positioning and boundary logic for + the fittable layout strategy. The fittable layout strategy is based on + laying out items in either a set of rows or a set of columns, with most of + the items having natural size, but one item expanding to fill the remaining + space. The item that expands is labeled with the attribute _fit: true_. + + For example, in the following kind, the second component fills the available + space in the container between the first and third components. + + enyo.kind({ + kind: "FittableRows", + components: [ + {content: "1"}, + {content: "2", fit:true}, + {content: "3"} + ] + }); + + <a href="#enyo.FittableColumnsLayout">enyo.FittableColumnsLayout</a> and + <a href="#enyo.FittableRowsLayout">enyo.FittableRowsLayout</a> (or their + subkinds) are used for layout rather than _enyo.FittableLayout_ because they + specify properties that _enyo.FittableLayout_ expects to be available when + laying items out. +*/ +enyo.kind({ + name: "enyo.FittableLayout", + kind: "Layout", + //* @protected + calcFitIndex: function() { + for (var i=0, c$=this.container.children, c; c=c$[i]; i++) { + if (c.fit && c.showing) { + return i; + } + } + }, + getFitControl: function() { + var c$=this.container.children; + var f = c$[this.fitIndex]; + if (!(f && f.fit && f.showing)) { + this.fitIndex = this.calcFitIndex(); + f = c$[this.fitIndex]; + } + return f; + }, + getLastControl: function() { + var c$=this.container.children; + var i = c$.length-1; + var c = c$[i]; + while ((c=c$[i]) && !c.showing) { + i--; + } + return c; + }, + _reflow: function(measure, cMeasure, mAttr, nAttr) { + this.container.addRemoveClass("enyo-stretch", !this.container.noStretch); + var f = this.getFitControl(); + // no sizing if nothing is fit. + if (!f) { + return; + } + // + // determine container size, available space + var s=0, a=0, b=0, p; + var n = this.container.hasNode(); + // calculate available space + if (n) { + // measure 1 + p = enyo.FittableLayout.calcPaddingExtents(n); + // measure 2 + s = n[cMeasure] - (p[mAttr] + p[nAttr]); + //console.log("overall size", s); + } + // + // calculate space above fitting control + // measure 3 + var fb = f.getBounds(); + // offset - container padding. + a = fb[mAttr] - ((p && p[mAttr]) || 0); + //console.log("above", a); + // + // calculate space below fitting control + var l = this.getLastControl(); + if (l) { + // measure 4 + var mb = enyo.FittableLayout.getComputedStyleValue(l.hasNode(), "margin", nAttr) || 0; + if (l != f) { + // measure 5 + var lb = l.getBounds(); + // fit offset + size + var bf = fb[mAttr] + fb[measure]; + // last offset + size + ending margin + var bl = lb[mAttr] + lb[measure] + mb; + // space below is bottom of last item - bottom of fit item. + b = bl - bf; + } else { + b = mb; + } + } + + // calculate appropriate size for fit control + var fs = s - (a + b); + //console.log(f.id, fs); + // note: must be border-box; + f.applyStyle(measure, fs + "px"); + }, + //* @public + /** + Updates the layout to reflect any changes to contained components or the + layout container. + */ + reflow: function() { + if (this.orient == "h") { + this._reflow("width", "clientWidth", "left", "right"); + } else { + this._reflow("height", "clientHeight", "top", "bottom"); + } + }, + statics: { + //* @protected + _ieCssToPixelValue: function(inNode, inValue) { + var v = inValue; + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + var s = inNode.style; + // store style and runtime style values + var l = s.left; + var rl = inNode.runtimeStyle && inNode.runtimeStyle.left; + // then put current style in runtime style. + if (rl) { + inNode.runtimeStyle.left = inNode.currentStyle.left; + } + // apply given value and measure its pixel value + s.left = v; + v = s.pixelLeft; + // finally restore previous state + s.left = l; + if (rl) { + s.runtimeStyle.left = rl; + } + return v; + }, + _pxMatch: /px/i, + getComputedStyleValue: function(inNode, inProp, inBoundary, inComputedStyle) { + var s = inComputedStyle || enyo.dom.getComputedStyle(inNode); + if (s) { + return parseInt(s.getPropertyValue(inProp + "-" + inBoundary)); + } else if (inNode && inNode.currentStyle) { + var v = inNode.currentStyle[inProp + enyo.cap(inBoundary)]; + if (!v.match(this._pxMatch)) { + v = this._ieCssToPixelValue(inNode, v); + } + return parseInt(v); + } + return 0; + }, + //* Gets the boundaries of a node's margin or padding box. + calcBoxExtents: function(inNode, inBox) { + var s = enyo.dom.getComputedStyle(inNode); + return { + top: this.getComputedStyleValue(inNode, inBox, "top", s), + right: this.getComputedStyleValue(inNode, inBox, "right", s), + bottom: this.getComputedStyleValue(inNode, inBox, "bottom", s), + left: this.getComputedStyleValue(inNode, inBox, "left", s) + }; + }, + //* Gets the calculated padding of a node. + calcPaddingExtents: function(inNode) { + return this.calcBoxExtents(inNode, "padding"); + }, + //* Gets the calculated margin of a node. + calcMarginExtents: function(inNode) { + return this.calcBoxExtents(inNode, "margin"); + } + } +}); + +/** + _enyo.FittableColumnsLayout_ provides a container in which items are laid + out in a set of vertical columns, with most of the items having natural + size, but one expanding to fill the remaining space. The one that expands is + labeled with the attribute _fit: true_. + + _enyo.FittableColumnsLayout_ is meant to be used as a value for the + _layoutKind_ property of other kinds. _layoutKind_ provides a way to add + layout behavior in a pluggable fashion while retaining the ability to use a + specific base kind. + + For example, the following code will align three components as columns, with + the second filling the available container space between the first and third. + + enyo.kind({ + kind: enyo.Control, + layoutKind: "FittableColumnsLayout", + components: [ + {content: "1"}, + {content: "2", fit:true}, + {content: "3"} + ] + }); + + Alternatively, if a specific base kind is not needed, then instead of + setting the _layoutKind_ attribute, you can set the base kind to + <a href="#enyo.FittableColumns">enyo.FittableColumns</a>: + + enyo.kind({ + kind: "FittableColumns", + components: [ + {content: "1"}, + {content: "2", fit:true}, + {content: "3"} + ] + }); +*/ +enyo.kind({ + name: "enyo.FittableColumnsLayout", + kind: "FittableLayout", + orient: "h", + layoutClass: "enyo-fittable-columns-layout" +}); + + +/** + _enyo.FittableRowsLayout_ provides a container in which items are laid out + in a set of horizontal rows, with most of the items having natural size, but + one expanding to fill the remaining space. The one that expands is labeled + with the attribute _fit: true_. + + _enyo.FittableRowsLayout_ is meant to be used as a value for the + _layoutKind_ property of other kinds. _layoutKind_ provides a way to add + layout behavior in a pluggable fashion while retaining the ability to use a + specific base kind. + + For example, the following code will align three components as rows, with + the second filling the available container space between the first and third. + + enyo.kind({ + kind: enyo.Control, + layoutKind: "FittableRowsLayout", + components: [ + {content: "1"}, + {content: "2", fit:true}, + {content: "3"} + ] + }); + + Alternatively, if a specific base kind is not needed, then instead of + setting the _layoutKind_ attribute, you can set the base kind to + <a href="#enyo.FittableRows">enyo.FittableRows</a>: + + enyo.kind({ + kind: "FittableRows", + components: [ + {content: "1"}, + {content: "2", fit:true}, + {content: "3"} + ] + }); +*/ +enyo.kind({ + name: "enyo.FittableRowsLayout", + kind: "FittableLayout", + layoutClass: "enyo-fittable-rows-layout", + orient: "v" +}); diff --git a/html/lib/layout/fittable/source/FittableRows.js b/html/lib/layout/fittable/source/FittableRows.js new file mode 100644 index 0000000..985f82d --- /dev/null +++ b/html/lib/layout/fittable/source/FittableRows.js @@ -0,0 +1,40 @@ +/** + _enyo.FittableRows_ provides a container in which items are laid out in a + set of horizontal rows, with most of the items having natural size, but one + expanding to fill the remaining space. The one that expands is labeled with + the attribute _fit: true_. + + For example, the following code will align three components as rows, with + the second filling the available container space between the first and third. + + enyo.kind({ + kind: "FittableRows", + components: [ + {content: "1"}, + {content: "2", fit:true}, + {content: "3"} + ] + }); + + Alternatively, you may set a kind's _layoutKind_ property to + <a href="#enyo.FittableRowsLayout">enyo.FittableRowsLayout</a> + to use a different base kind while still employing the fittable layout + strategy, e.g.: + + enyo.kind({ + kind: enyo.Control, + layoutKind: "FittableRowsLayout", + components: [ + {content: "1"}, + {content: "2", fit:true}, + {content: "3"} + ] + }); +*/ +enyo.kind({ + name: "enyo.FittableRows", + layoutKind: "FittableRowsLayout", + /** By default, items in rows stretch to fit horizontally; set to true to + avoid this behavior. */ + noStretch: false +}); diff --git a/html/lib/layout/fittable/source/design.js b/html/lib/layout/fittable/source/design.js new file mode 100644 index 0000000..ab94505 --- /dev/null +++ b/html/lib/layout/fittable/source/design.js @@ -0,0 +1,23 @@ +/** + Description to make fittable kinds available in Ares. +*/ +Palette.model.push( + {name: "fittable", items: [ + {name: "FittableRows", title: "Vertical stacked layout", icon: "package_new.png", stars: 4.5, version: 2.0, blurb: "Stack of vertical rows, one of which can be made to fit.", + inline: {kind: "FittableRows", style: "height: 80px; position: relative;", padding: 4, components: [ + {style: "background-color: lightblue; border: 1px dotted blue; height: 15px;"}, + {style: "background-color: lightblue; border: 1px dotted blue;", fit: true}, + {style: "background-color: lightblue; border: 1px dotted blue; height: 15px;"} + ]}, + config: {content: "$name", isContainer: true, kind: "FittableRows", padding: 10, margin: 10} + }, + {name: "FittableColumns", title: "Horizontal stacked layout", icon: "package_new.png", stars: 4.5, version: 2.0, blurb: "Stack of horizontal columns, one of which can be made to fit.", + inline: {kind: "FittableColumns", style: "height: 60px; position: relative;", padding: 4, components: [ + {style: "background-color: lightblue; border: 1px dotted blue; width: 20px;"}, + {style: "background-color: lightblue; border: 1px dotted blue;", fit: true}, + {style: "background-color: lightblue; border: 1px dotted blue; width: 20px;"} + ]}, + config: {content: "$name", isContainer: true, kind: "FittableColumns", padding: 10, margin: 10} + } + ]} +);
\ No newline at end of file diff --git a/html/lib/layout/fittable/source/package.js b/html/lib/layout/fittable/source/package.js new file mode 100644 index 0000000..74201af --- /dev/null +++ b/html/lib/layout/fittable/source/package.js @@ -0,0 +1,6 @@ +enyo.depends( + "FittableLayout.css", + "FittableLayout.js", + "FittableRows.js", + "FittableColumns.js" +);
\ No newline at end of file |