388 lines
11 KiB
JavaScript
388 lines
11 KiB
JavaScript
//vim: et:ts=4:sw=4:sts=4:ft=js
|
|
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
|
|
var self = self || {},
|
|
that = new Ox.Element('div', 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 = new Ox.Bar({
|
|
size: 'medium'
|
|
})
|
|
.addClass('OxTitleBar')
|
|
.appendTo(that);
|
|
self.options.movable && that.$titlebar
|
|
.dblclick(center)
|
|
.bindEvent({
|
|
dragstart: dragstart,
|
|
drag: drag
|
|
});
|
|
|
|
that.$title = new Ox.Element()
|
|
.addClass('OxTitle')
|
|
.html(self.options.title)
|
|
.appendTo(that.$titlebar);
|
|
|
|
that.$content = new Ox.Element()
|
|
.addClass('OxContent')
|
|
.css({
|
|
padding: self.options.padding + 'px',
|
|
overflow: 'auto'
|
|
})
|
|
.append(self.options.content)
|
|
.appendTo(that);
|
|
|
|
that.$buttonsbar = new Ox.Bar({})
|
|
.addClass('OxButtonsBar')
|
|
.appendTo(that);
|
|
loadButtons();
|
|
|
|
//that.$buttons[0].focus();
|
|
|
|
that.$layer = new 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 = new 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.onChange = 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;
|
|
|
|
};
|