')`, with
+ proper chaining. If you have `var $d = $('
'), $e =
+ Ox.Element();`, then `$d.appendTo($e)` returns `$d`, and
+ `$e.append($d)` returns `$e`.
+ */
+ that.css({
+ backgroundColor: 'rgb(' + self.options.color.join(', ') + ')',
+ });
+ }
+
+ function setSize() {
+ /*
+ Before setting the size, we make sure the value is between minSize
+ and maxSize.
+ */
+ self.options.size = Ox.limit(
+ self.options.size, self.minSize, self.maxSize
+ );
+ that.css({
+ height: self.options.size + 'px',
+ width: self.options.size + 'px'
+ });
+ }
+
+ /*
+ Next, we define the widgets public methods, as properties of `that`.
+ (Note that unlike private methods, they are not hoisted.)
+ */
+ that.showOptions = function() {
+ /*
+ As there isn't much to do yet, this method just displays the
+ widget's options.
+ */
+ that.html(JSON.stringify(self.options).replace(/([,:])/g, '$1 '));
+ /*
+ Public methods should return `that`, for chaining.
+ */
+ return that;
+ };
+
+ /*
+ At the very end of the "constructor", we always return `that`. And
+ that's it.
+ */
+ return that;
+
+ };
+
+ /*
+ `Ox.My.Box({size: 256}).appendTo(Ox.$body).showOptions()`
+ */
+
+ window.myBox = Ox.My.Box().appendTo(Ox.$body);
+ return;
+
+ Ox.My.Box = function(options, self) {
+
+ self = self || {};
+ var that = Ox.Element('
', self)
+ .defaults({
+ color: [128, 128, 128],
+ size: 128
+ })
+ .options(options || {})
+ .addClass('OxMyBox OxMonospace')
+ .css({
+ color: 'white',
+ padding: '16px',
+ textShadow: '1px 1px 1px black'
+ })
+ .bindEvent({
+ anyclick: focus,
+ key_0: reset,
+ key_equal: function() {
+ Ox.print('+', self.options.size)
+ setSize(self.options.size + 16, true);
+ },
+ key_minus: function() {
+ setSize(self.options.size - 16, true);
+ }
+ });
+
+ self.initialSize = self.options.size;
+ self.minSize = 128;
+ self.maxSize = 384;
+
+ setColor();
+ setSize(self.options.size);
+ showOptions();
+
+ function focus(e) {
+ Ox.print(e.target);
+ if (e.target == that.$element[0]) {
+ that.gainFocus();
+ }
+ }
+
+ function setColor() {
+ that.css({
+ backgroundColor: 'rgb(' + self.options.color.join(', ') + ')',
+ });
+ }
+
+ function setSize(size, animate) {
+ var css;
+ self.options.size = Ox.limit(size, self.minSize, self.maxSize);
+ css = {
+ height: self.options.size + 'px',
+ width: self.options.size + 'px',
+ };
+ Ox.print('SET SIZE', size, animate, self.minSize, self.maxSize, css)
+ if (animate) {
+ that.stop().animate(css, 100, showOptions);
+ } else {
+ that.css(css);
+ }
+ }
+
+ function showOptions() {
+ try {
+ that.html(JSON.stringify(self.options).replace(/([,:])/g, '$1 '));
+ } catch(e) {}
+ }
+
+ function reset() {
+ self.options = self.initialOptions;
+ showOptions();
+ }
+
+ self.setOption = function(key, value) {
+ if (key == 'color') {
+ setColor();
+ } else if (key == 'size') {
+ setSize(value);
+ }
+ showOptions();
+ };
+
+ return that;
+
+ };
+
+ Ox.My.RoundedBox = function(options, self) {
+
+ self = self || {};
+ var that = Ox.My.Box({}, self);
+ that.defaults(Ox.extend(that.defaults(), {
+ radius: 16
+ }))
+ .options(options || {});
+
+ setRadius();
+
+ function setRadius() {
+ that.css({
+ MozBorderRadius: self.options.radius + 'px',
+ OBorderRadius: self.options.radius + 'px',
+ WebkitBorderRadius: self.options.radius + 'px'
+ });
+ }
+
+ self.setSuperOption = self.setOption;
+
+ self.setOption = function(key, value) {
+ if (key == 'radius') {
+ setRadius();
+ } else {
+ self.setSuperOption(key, value);
+ }
+ }
+
+ return that;
+
+ };
+
+ Ox.My.MetaBox = function(options, self) {
+
+ self = self || {};
+ Ox.print('MB', options)
+ var that = Ox.My.Box({}, self);
+ that.defaults(Ox.extend(that.defaults(), {
+ boxes: []
+ }))
+ .options(options || {});
+
+ self.options.boxes.forEach(function(box) {
+ that.append(box);
+ });
+
+ return that;
+
+ };
+
+ Ox.My.MetaBox({
+ boxes: [
+ Ox.My.Box({
+ color: [64, 128, 255]
+ }),
+ Ox.My.RoundedBox({
+ color: [255, 128, 64]
+ })
+ ],
+ size: 384
+ })
+ .appendTo(Ox.$body);
+
+});
\ No newline at end of file