/** * @requirefiles {Iterator.js,controls/GlobalControlManager.js} */ $(window).bind('contextmenu', null, Control_ContextMenu); $(window).bind('keydown', null, Control_Keydown); $(window).bind('keypress', null, Control_Keypress); $(window).bind('keyup', null, Control_Keyup); $(window).bind('mousedown', null, Control_Mousedown); $(window).bind('mouseup', null, Control_Mouseup); $(window).bind('mousewheel', null, Control_Mousewheel); /** * Creates an instance of a new Control, should only be called when creating derivative controls. * @param {Object} [settings] The properties object used in the creation of the control. * @abstract * @class */ function Control(settings) { } /** * Causes control instance to be blurred and fire off associated events, while bubbling up through containing controls. * @function * @name Control#Blur */ function Control_Blur() { if (this.Focused === true) { this.Focused = false; if (this.Focusables !== null) { if (this.Focusables instanceof Array) { for (let i = 0; i < this.Focusables.length; i++) { if (this.Focusables[i].hasClass('focus')) { this.Focusables[i].removeClass('focus'); } } } else { this.Focusables.removeClass('focus'); } } if (this.ParentControl !== null) { this.ParentControl.Blur(); } } if (this.AfterBlur) { this.AfterBlur(); } } /** * Fires off a context menu request for the control if available, otherwise bubbles up to containing controls. * @function * @name Control#Blur * @param {IJQueryEventObject} event The contextmenu event object. */ function Control_ContextMenu(event) { if(window.ControlGlobal.DirtyContextMenu === true) { window.ControlGlobal.DirtyContextMenu = false; event.stopPropagation(); } else { let ctl = window.ControlGlobal.Controls[window.ControlGlobal.Controls.length - 1]; if ((ctl !== null) && (ctl.ContextMenu) && (ctl.ContextMenu !== Control_ContextMenu)) { event.data = ctl; ctl.ContextMenu(event); event.stopPropagation(); } } event.preventDefault(); } /** * Disposes of the base control instance and frees up allocated resources. * @function * @name Control#Dispose */ function Control_Dispose() { if (this.Focusables != null) { if (this.Focusables instanceof Array) { for (let i = 0; i < this.Focusables.length; i++) { this.Focusables[i].unbind('contextmenu', Control_ContextMenu); this.Focusables[i].unbind('mousedown', Control_Mousedown); this.Focusables[i].unbind('mousewheel', Control_Mousewheel); } } else { this.Focusables.unbind('contextmenu', Control_ContextMenu); this.Focusables.unbind('mousedown', Control_Mousedown); this.Focusables.unbind('mousewheel', Control_Mousewheel); } } window.ControlGlobal.Iterator.recycleSync(this.ControlUniqueID); this.ControlUniqueID = null; } /** * Causes control instance to be focused if available while firing off associated events, while bubbling up through containing controls when the control instance cannot receive focus. * @function * @name Control#Focus * @param {boolean} [last=false] Causes focus to bubble down into contained controls. */ function Control_Focus(last) { if (arguments.length < 1) { last = false; } if ((this.ParentControl !== null) && (this.ParentControl.Focused === false)) { this.ParentControl.Focus(); } if (this.Focused === false) { this.Focused = true; if (this.Focusables != null) { if (this.Focusables instanceof Array) { for (let i = 0; i < this.Focusables.length; i++) { if ((this.Focusables[i] !== null) && (!this.Focusables[i].hasClass('focus'))) { this.Focusables[i].addClass('focus'); } } } else { this.Focusables.addClass('focus'); } } } if (last === true) { for (let i = window.ControlGlobal.Controls.length - 1; i >= 0; i--) { if (window.ControlGlobal.Controls[i].ControlUniqueID !== this.ControlUniqueID) { if ((window.ControlGlobal.Controls[i].ParentControl !== null) && (window.ControlGlobal.Controls[i].ParentControl.ControlUniqueID === this.ControlUniqueID)) { window.ControlGlobal.Controls[i].Focus(true); break; } } } } if (this.AfterFocus) { this.AfterFocus(); } } /** * Initializes an instance of a control. * @function * @name Control#Initialize * @param {Array} args Arguments used to instantiate derived control. * @param {Control} parentControl Parent control, if applicable. * @param {JQuery[]} focusables Array of focusable elements. */ function Control_Initialize(args, parentControl, focusables) { /** * The containing control. * @name Control#ParentControl * @type {Control} */ this.ParentControl = ((parentControl !== null) && (parentControl !== undefined) ? parentControl : null); /** * List of elements which should have focus related CSS classes set and events hooked. * @name Control#Focusables * @type {JQuery[]} */ this.Focusables = ((focusables !== null) && (focusables !== undefined) && (focusables instanceof Array) ? focusables : []); /** * Whether or not the control actively has focus. * @name Control#Focused * @type {boolean} */ this.Focused = false; /** * Determines whether or not the control may receive focus. * @name Control#CanGetFocus * @type {boolean} */ if (!this.hasOwnProperty('CanGetFocus')) { this.CanGetFocus = false; } /** * Determines whether or not the control may receive focus via the tab key. * @name Control#CanTabFocus * @type {boolean} */ if (!this.hasOwnProperty('CanTabFocus')) { this.CanTabFocus = false; } //this.AfterBlur = null; //this.AfterFocus = null; /** * The globally-unique ID of the control. * @name Control#ControlUniqueID * @type {number} */ this.ControlUniqueID = window.ControlGlobal.Iterator.getNextIdSync(); window.ControlGlobal.Controls.push(this); /** * Arguments used to instantiate the control. * @name Control#Arguments * @type {Array} */ this.Arguments = ((args !== null) && (args !== undefined) && (args instanceof Array) ? args : []); /** * Control which should receive focus in place of this one. * @name Control#ForFocus * @type {Control} */ this.ForFocus = ((this.Arguments !== undefined) && (this.Arguments[0] !== undefined) && this.Arguments[0].hasOwnProperty('ForFocus') ? this.Arguments[0]['ForFocus'] : null); /** * The tab index of the control determines which order controls may shift focus via the tab key. * @name Control#TabIndex * @type {number} */ this.TabIndex = (this.CanTabFocus === true ? ((this.Arguments !== undefined) && (this.Arguments[0] !== undefined) && this.Arguments[0].hasOwnProperty('TabIndex') ? parseInt(this.Arguments[0]['TabIndex']) : 0) : false); if (this.Focusables !== null) { if (this.Focusables instanceof Array) { for (let i = 0; i < this.Focusables.length; i++) { this.Focusables[i].bind('contextmenu', this, Control_ContextMenu); this.Focusables[i].bind('mousedown', this, Control_Mousedown); this.Focusables[i].bind('mouseup', this, Control_Mouseup); this.Focusables[i].bind('mousewheel', this, Control_Mousewheel); } } else { this.Focusables.bind('contextmenu', this, Control_ContextMenu); this.Focusables.bind('mousedown', this, Control_Mousedown); this.Focusables.bind('mouseup', this, Control_Mouseup); this.Focusables.bind('mousewheel', this, Control_Mousewheel); } } } /** * Handles the keydown event for a control. * @function * @name Control#Keydown * @param {IJQueryEventObject} event The keydown event object. */ function Control_Keydown(event) { if (ContextMenuGlobal.Active !== null) { if (ContextMenuGlobal.Active.Keydown(event) === true) { event.preventDefault(); return (false); } else { return; } } for (let i = window.ControlGlobal.Controls.length - 1; i >= 0; i--) { let ctl = window.ControlGlobal.Controls[i]; if (ctl !== null) { let returnCode = 0; if ((ctl.Keydown) && (ctl.Keydown !== Control_Keydown)) { returnCode = ctl.Keydown(event); } if ((returnCode !== false) && (returnCode !== true) && (event.keyCode === 9)) { if (ctl.hasOwnProperty('ParentControl') && (ctl['ParentControl'] !== null)) { if (event.shiftKey === true) { ctl.ParentControl.Controls.FocusPrevious(); } else { ctl.ParentControl.Controls.FocusNext(); } event.preventDefault(); return; } } else { break; } } } if ((event.ctrlKey === true) && (event.keyCode === 65)) { event.preventDefault(); } } /** * Handles the keypress event for a control. * @function * @name Control#Keypress * @param {IJQueryEventObject} event The keypress event object. */ function Control_Keypress(event) { if (ContextMenuGlobal.Active !== null) { if (ContextMenuGlobal.Active.Keypress(event) === true) { event.preventDefault(); return (false); } else {return; } } for (let i = window.ControlGlobal.Controls.length - 1; i >= 0; i--) { let ctl = window.ControlGlobal.Controls[window.ControlGlobal.Controls.length - 1]; if ((ctl !== null) && (ctl.Keypress) && (ctl.Keypress !== Control_Keypress)) { ctl.Keypress(event); break; } } } /** * Handles the keyup event for a control. * @function * @name Control#Keyup * @param {IJQueryEventObject} event The keyup event object. */ function Control_Keyup(event) { if (ContextMenuGlobal.Active !== null) { if (ContextMenuGlobal.Active.Keyup(event) === true) { event.preventDefault(); return (false); } else { return; } } for (let i = window.ControlGlobal.Controls.length - 1; i >= 0; i--) { let ctl = window.ControlGlobal.Controls[window.ControlGlobal.Controls.length - 1]; if ((ctl !== null) && (ctl.Keyup) && (ctl.Keyup !== Control_Keyup)) { ctl.Keyup(event); break; } } } /** * Handles the mousedown event for a control. * @function * @name Control#Mousedown * @param {IJQueryEventObject} event The mousedown event object. */ function Control_Mousedown(event) { if (event.data !== null) { if (window.ControlGlobal.DirtyMouseDown === false) { window.ControlGlobal.DirtyMouseDown = true; window.ControlGlobal.Controls.Activate(event.data); let ret = undefined; if (event.data.Mousedown && (event.data.Mousedown !== Control_Mousedown)) { ret = event.data.Mousedown(event); } if (ret !== undefined) { return (ret); } } //event.preventDefault(); } else { window.ControlGlobal.DirtyMouseDown = false; } } /** * Handles the mouseup event for a control. * @function * @name Control#Mouseup * @param {IJQueryEventObject} event The mouseup event object. */ function Control_Mouseup(event) { if (event.data !== null) { if (window.ControlGlobal.DirtyMouseDown === false) { window.ControlGlobal.DirtyMouseDown = true; window.ControlGlobal.Controls.Activate(event.data); let ret = undefined; if (event.data.Mouseup && (event.data.Mouseup !== Control_Mouseup)) { ret = event.data.Mouseup(event); } if (ret !== undefined) { return (ret); } } //event.preventDefault(); } else { window.ControlGlobal.DirtyMouseDown = false; } } /** * Handles the mousewheel event for a control * @function * @name Control#Mousewheel * @param {IJQueryEventObject} event The mousewheel event object. */ function Control_Mousewheel(event) { if (event.data !== null) { let ret = undefined; if (event.data.Mousewheel && (event.data.Mousewheel !== Control_Mousewheel)) { ret = event.data.Mousewheel(event); } if (ret !== undefined) { return (ret); } } } Control.prototype.constructor = Control; Control.prototype.Blur = Control_Blur; Control.prototype.ContextMenu = Control_ContextMenu; Control.prototype.Dispose = Control_Dispose; Control.prototype.Focus = Control_Focus; Control.prototype.Initialize = Control_Initialize; Control.prototype.Keydown = Control_Keydown; Control.prototype.Keypress = Control_Keypress; Control.prototype.Keyup = Control_Keyup; Control.prototype.Mousedown = Control_Mousedown; Control.prototype.Mouseup = Control_Mouseup; Control.prototype.Mousewheel = Control_Mousewheel; /** * Tells a control to render itself in an activated state. * @name Control#Activate * @function */ /** * Tells a control to render itself in a deactivated state. * @name Control#Deactivate * @function */ /** * JQuery event object used in conjunction with keyboard and mouse events. * @interface IJQueryEventObject */ /** * Prevents the default action of the event. * @function IJQueryEventObject#preventDefault * @instance */ /** * Stops propagation of the event. * @function IJQueryEventObject#stopPropagation * @instance */ /** * Whether or not the ALT key was down during the event. * @name IJQueryEventObject#altKey * @type {boolean} */ /** * Whether or not the CTRL key was down during the event. * @name IJQueryEventObject#ctrlKey * @type {boolean} */ /** * Whether or not the META key was down during the event. * @name IJQueryEventObject#metaKey * @type {boolean} */ /** * Whether or not the SHIFT key was down during the event. * @name IJQueryEventObject#shiftKey * @type {boolean} */ /** * The keycode of the event. * @name IJQueryEventObject#keyCode * @type {number} */ /** * Data object associated with the event. * @name IJQueryEventObject#data * @type {*} */