// vim: et:ts=4:sw=4:sts=4:ft=js // check out http://ejohn.org/apps/learn/#36 (-#38, making fns work w/o new) Ox.Element = function() { /*** Basic element object ***/ /* tooltip option can be any of the following: string function(e), returns string {mousemove: true, title: function(e)} */ return function(options, self) { /* // allow for 'Ox.Element()' instead of 'new Ox.Element()' if (!(this instanceof arguments.callee)) { return new arguments.callee(options, self); } */ // create private object self = self || {}; // create defaults and options objects self.defaults = {}; self.options = options || {}; // allow for Ox.TestElement('') // or Ox.TestElement('cssSelector') if (Ox.isString(self.options)) { self.options = { element: self.options } }; // create event handler if (!self.$eventHandler) { self.$eventHandler = $('
'); } // create public object var that = new Ox.JQueryElement( $(self.options.element || '
') ) .mousedown(mousedown); /* self.options.tooltip && that.bind(Ox.extend({ mouseenter: mouseenter, mouseleave: mouseleave }, self.options.tooltip.mousemove ? { mousemove: mousemove } : {})); */ function mousedown(e) { /* better mouse events mousedown: trigger mousedown within 250 msec: mouseup: trigger anyclick ("click" would collide with click events of certain widgets) mouseup + mousedown: trigger doubleclick after 250 msec: mouseup + no mousedown within 250 msec: trigger singleclick no mouseup within 250 msec: trigger mouserepeat every 50 msec trigger dragstart mousemove: trigger drag no mousemove within 250 msec: trigger dragpause mouseup: trigger dragend */ var clientX, clientY, dragTimeout = 0, mouseInterval = 0; if (!self.mouseTimeout) { // first mousedown that.triggerEvent('mousedown', e); self.mouseup = false; self.mouseTimeout = setTimeout(function() { self.mouseTimeout = 0; if (self.mouseup) { // singleclick that.triggerEvent('singleclick', e); } else { // mouserepeat, drag clientX = e.clientX; clientY = e.clientY; that.triggerEvent('dragstart', e); mouserepeat(); mouseInterval = setInterval(mouserepeat, 50); Ox.UI.$window.unbind('mouseup', mouseup) .mousemove(mousemove) .one('mouseup', function(e) { clearInterval(mouseInterval); clearTimeout(dragTimeout); Ox.UI.$window.unbind('mousemove', mousemove); that.triggerEvent('dragend', extend(e)); }); that.one('mouseleave', function() { clearInterval(mouseInterval); }); } }, 250); } else { // second mousedown clearTimeout(self.mouseTimeout); self.mouseTimeout = 0; that.triggerEvent('doubleclick', e); } Ox.UI.$window.one('mouseup', mouseup); function extend(e) { return Ox.extend({ clientDX: e.clientX - clientX, clientDY: e.clientY - clientY }, e); } function mousemove(e) { e = extend(e); clearTimeout(dragTimeout); dragTimeout = setTimeout(function() { that.triggerEvent('dragpause', e); }, 250); that.triggerEvent('drag', e); } function mouserepeat() { that.triggerEvent('mouserepeat'); } function mouseup(e) { // only trigger on firse mouseup if (!self.mouseup) { that.triggerEvent('anyclick', e); self.mouseup = true; } } } /* function mouseenter(e) { self.$tooltip = new Ox.Tooltip({ title: Ox.isString(self.options.tooltip) ? self.options.tooltip : Ox.isFunction(self.options.tooltip) ? self.options.tooltip(e) : self.options.tooltip.title(e) }).show(); } function mouseleave(e) { self.$tooltip.hide(); } function mousemove(e) { self.$tooltip.options({ title: self.options.tooltip.title(e) }); } */ self.setOption = function() { // self.setOptions(key, value) // is called when an option changes // (to be implemented by widget) }; that._self = self; // fixme: remove that.bindEvent = function() { /*** binds a function to an event triggered by this object Usage bindEvent(event, fn) or bindEvent({event0: fn0, event1: fn1, ...}) ***/ if (arguments.length == 1) { Ox.forEach(arguments[0], function(fn, event) { // Ox.print(that.id, 'bind', event); self.$eventHandler.bind('ox_' + event, fn); }); } else { // Ox.print(that.id, 'bind', arguments[0]); self.$eventHandler.bind('ox_' + arguments[0], arguments[1]); } return that; } that.bindEventOnce = function() { if (arguments.length == 1) { Ox.forEach(arguments[0], function(fn, event) { self.$eventHandler.one('ox_' + event, fn); }); } else { self.$eventHandler.one('ox_' + arguments[0], arguments[1]); } return that; }; that.defaults = function(defaults) { // sets the default options self.defaults = defaults; self.options = defaults; return that; }; that.gainFocus = function() { /*** make this object gain focus ***/ Ox.Focus.focus(that.id); return that; }; that.hasFocus = function() { /*** returns true if this object has focus ***/ return Ox.Focus.focused() == that.id; }; that.loseFocus = function() { /*** make this object lose focus ***/ Ox.Focus.blur(that.id); return that; }; that.options = function() { /* that.options() returns self.options that.options(key) returns self.options.key that.options(key, val) sets self.options.key to val, calls self.setOption(key, val) if the key has been added or its val has changed, returns that that.options({keyA: valA, keyB: valB}) sets self.options.keyA to valA and self.options.keyB to valB, calls self.setOptions(key, val) for every key/value pair that has been added or modified, returns that */ return Ox.getset(self.options, arguments, self.setOption, that); }; that.removeElement = function() { /*** remove this element, including its event handler ***/ that.loseFocus(); delete self.$eventHandler; that.remove(); delete Ox.UI.elements[that.id]; return that; }; that.triggerEvent = function() { /*** triggers an event Usage triggerEvent(event) triggerEvent(event, data) triggerEvent({event0: data0, event1: data1, ...}) ***/ if (Ox.isObject(arguments[0])) { Ox.forEach(arguments[0], function(data, event) { if (['mousedown', 'mouserepeat', 'anyclick', 'singleclick', 'doubleclick', 'dragstart', 'drag', 'dragpause', 'dragend', 'playing'].indexOf(event) == -1) { Ox.print(that.id, self.options.id, 'trigger', event, data); } self.$eventHandler.trigger('ox_' + event, data); }); } else { if (['mousedown', 'mouserepeat', 'anyclick', 'singleclick', 'doubleclick', 'dragstart', 'drag', 'dragpause', 'dragend', 'playing'].indexOf(arguments[0]) == -1) { Ox.print(that.id, self.options ? self.options.id : '', 'trigger', arguments[0], arguments[1] || {}); } self.$eventHandler.trigger('ox_' + arguments[0], arguments[1] || {}); } return that; }; that.unbindEvent = function() { /*** unbinds a function from an event triggered by this element Usage unbindEvent(event, fn) unbindEvent({event0: fn0, event1: fn1, ...}) ***/ if (arguments.length == 1) { Ox.forEach(arguments[0], function(fn, event) { // Ox.print(that.id, 'unbind', arguments[0]); self.$eventHandler.unbind('ox_' + event, fn); }); } else { // Ox.print(that.id, 'unbind', arguments[0]); self.$eventHandler.unbind('ox_' + arguments[0], arguments[1]); } return that; }; return that; } }();