// vim: et:ts=4:sw=4:sts=4:ft=js /*@ Ox.Dialog Dialog Object () -> Dialog Object (options) -> Dialog Object (options, self) -> Dialog Object options Options object self shared private variable @*/ Ox.Dialog = function(options, self) { // fixme: dialog should be derived from a generic draggable // fixme: buttons should have a close attribute, or the dialog a close id self = self || {}; var that = Ox.Element({}, self) .defaults({ title: '', buttons: [], content: null, height: 216, keys: {}, minHeight: 144, minWidth: 256, movable: true, padding: 16, resizable: true, width: 384 }) .options(options || {}) .addClass('OxDialog') .bindEvent({ key_enter: function() { keypress('enter'); }, key_escape: function() { //Ox.print('KEY ESCAPE') keypress('escape'); } }); $.extend(self, { initialWidth: self.options.width, initialHeight: self.options.height }); that.$titlebar = Ox.Bar({ size: 'medium' }) .addClass('OxTitleBar') .appendTo(that); self.options.movable && that.$titlebar .dblclick(center) .bindEvent({ dragstart: dragstart, drag: drag }); that.$title = Ox.Element() .addClass('OxTitle') .html(self.options.title) .appendTo(that.$titlebar); that.$content = Ox.Element() .addClass('OxContent') .css({ padding: self.options.padding + 'px', overflow: 'auto' }) .append(self.options.content) .appendTo(that); that.$buttonsbar = Ox.Bar({}) .addClass('OxButtonsBar') .appendTo(that); loadButtons(); //that.$buttons[0].focus(); that.$layer = Ox.Element() // fixme: Layer widget that would handle click? .addClass('OxLayer') .mousedown(mousedownLayer) .mouseup(mouseupLayer); function center() { var documentHeight = Ox.UI.$document.height(); that.css({ left: 0, top: Math.max(parseInt(-documentHeight / 10), self.options.height - documentHeight + 40) + 'px', right: 0, bottom: 0, margin: 'auto' }); } function dragstart(event, e) { self.drag = { bodyWidth: Ox.UI.$body.width(), bodyHeight: Ox.UI.$document.height(), elementWidth: that.width(), offset: that.offset(), x: e.clientX, y: e.clientY }; that.css({ margin: 0 }); } function drag(event, e) { var left = Ox.limit( self.drag.offset.left - self.drag.x + e.clientX, 24 - self.drag.elementWidth, self.drag.bodyWidth - 24 //0, self.drag.documentWidth - self.drag.elementWidth ), top = Ox.limit( self.drag.offset.top - self.drag.y + e.clientY, 24, self.drag.bodyHeight - 24 //24, self.drag.documentHeight - self.drag.elementHeight ); that.css({ left: left + 'px', top: top + 'px' }); } function dragstartResize(event, e) { self.drag = { documentWidth: Ox.UI.$document.width(), documentHeight: Ox.UI.$document.height(), elementWidth: that.width(), elementHeight: that.height(), offset: that.offset(), x: e.clientX, y: e.clientY }; $.extend(self.drag, { ratio: self.drag.elementWidth / self.drag.elementHeight }); that.css({ left: self.drag.offset.left, top: self.drag.offset.top, margin: 0 }); } function dragResize(event, e) { if (!e.shiftKey) { self.drag.ratio = self.options.width / self.options.height; } self.options.width = Ox.limit( self.drag.elementWidth - self.drag.x + e.clientX, self.options.minWidth, Math.min( self.drag.documentWidth, self.drag.documentWidth - self.drag.offset.left ) ); self.options.height = Ox.limit( self.drag.elementHeight - self.drag.y + e.clientY, self.options.minHeight, Math.min( self.drag.documentHeight, self.drag.documentHeight - self.drag.offset.top ) ); if (e.shiftKey) { self.options.height = Ox.limit( self.options.width / self.drag.ratio, self.options.minHeight, Math.min( self.drag.documentHeight, self.drag.documentHeight - self.drag.offset.top ) ); self.options.width = self.options.height * self.drag.ratio; } that.width(self.options.width); that.height(self.options.height); that.$content.height(self.options.height - 48 - 2 * self.options.padding); // fixme: this should happen automatically } function dragendResize(event, e) { triggerResizeEvent(); } function getButtonById(id) { var ret = null; //Ox.print('that.$buttons', that.$buttons, id) Ox.forEach(that.$buttons, function(button) { if (button.options('id') == id) { ret = button; return false; } }); return ret; } function keypress(key) { var id = self.options.keys[key]; //Ox.print('X', key, self.options.keys) id && getButtonById(id).$element.trigger('click'); } function loadButtons() { /*Ox.print('loadButtons', $.map(self.options.buttons, function(v) { return v; }));*/ if (that.$buttons) { that.$buttons.forEach(function($button) { $button.removeElement(); }); that.$resize.removeElement(); // that.$buttonsbar.empty(); } that.$buttons = []; if (!Ox.isArray(self.options.buttons[0])) { self.options.buttons = [[], self.options.buttons]; } self.options.buttons[0].forEach(function(button, i) { that.$buttons[i] = button .addClass('OxLeft') .appendTo(that.$buttonsbar); }); if (self.options.resizable) { that.$resize = Ox.Element() .addClass('OxResize') .dblclick(reset) .bindEvent({ dragstart: dragstartResize, drag: dragResize, dragend: dragendResize }) .appendTo(that.$buttonsbar); } self.options.buttons[1].reverse().forEach(function(button) { that.$buttons[that.$buttons.length] = button .addClass('OxRight') .appendTo(that.$buttonsbar); }); } function mousedownLayer() { that.$layer.stop().animate({ opacity: 0.5 }, 0); } function mouseupLayer() { that.$layer.stop().animate({ opacity: 0 }, 0); } function reset() { $.extend(self.options, { height: self.initialHeight, width: self.initialWidth }); that/*.css({ left: Math.max(that.offset().left, 24 - that.width()) })*/ .width(self.options.width) .height(self.options.height); that.$content.height(self.options.height - 48 - 2 * self.options.padding); // fixme: this should happen automatically triggerResizeEvent(); } function triggerResizeEvent() { that.triggerEvent('resize', { width: self.options.width, height: self.options.height }); } self.setOption = function(key, value) { if (key == 'buttons') { loadButtons(); /* that.$buttonsbar.children().animate({ opacity: 0 }, 100, function() { loadButtons(); that.$buttonsbar.children().animate({ opacity: 1 }, 100); }); */ } else if (key == 'content') { that.$content.html(value); } else if (key == 'height' || key == 'width') { that.animate({ height: self.options.height + 'px', width: self.options.width + 'px' }, 100); that.$content.height(self.options.height - 48 - 2 * self.options.padding); // fixme: this should happen automatically } else if (key == 'title') { that.$title.animate({ opacity: 0 }, 100, function() { that.$title.html(value).animate({ opacity: 1 }, 100); }); } }; that.center = function() { }; that.close = function(callback) { callback = callback || function() {}; that.animate({ opacity: 0 }, 200, function() { that.$buttons.forEach(function($button) { $button.removeElement(); }); that.loseFocus(); that.$layer.removeElement(); that.removeElement(); callback(); }); Ox.UI.$window.unbind('mouseup', mouseupLayer); return that; }; that.content = function($element) { that.$content.empty().append($element); return that; }; that.disable = function() { // to be used on submit of form, like login that.$layer.addClass('OxFront'); return that; }; that.disableButton = function(id) { getButtonById(id).options({ disabled: true }); return that; }; that.enable = function() { that.$layer.removeClass('OxFront'); return that; }; that.enableButton = function(id) { getButtonById(id).options({ disabled: false }); return that; }; that.open = function() { //Ox.print('before open') that.$layer.appendTo(Ox.UI.$body); that.css({ opacity: 0 }).appendTo(Ox.UI.$body).animate({ opacity: 1 }, 200); center(); reset(); // fixme: the following line prevents preview-style dialog that.gainFocus(); Ox.UI.$window.bind('mouseup', mouseupLayer); //Ox.print('after open') return that; }; that.size = function(width, height, callback) { $.extend(self, { initialWidth: width, initialHeight: height }); $.extend(self.options, { width: width, height: height }); // fixme: duplicated that.animate({ height: self.options.height + 'px', width: self.options.width + 'px' }, 100, function() { that.$content.height(self.options.height - 48 - 2 * self.options.padding); // fixme: this should happen automatically callback(); }); }; return that; };