=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.mouse.js' --- src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.mouse.js 2016-04-09 16:41:00 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.mouse.js 2016-04-19 19:57:19 +0000 @@ -24,6 +24,9 @@ ** SBI 20160310 Added getEvents() to MouseMovable, fixed undeclared variable that was hidden ** by the variable "parent". ** 008 HC 20160406 Overhaul of window-activation logic. +** 009 SBI 20160419 MouseMovable, MousePopupable, WindowClose, WindowIconify, WindowMaximize, +** WindowStateChangedWorker are changed to catch mouse events from the global +** mouse events dispatcher. */ "use strict"; @@ -331,7 +334,7 @@ document.addEventListener("mousedown", processMouseDragStart("mousedown")); document.addEventListener("mouseup", processMouseDragStop ("mouseup")); document.addEventListener("mousemove", processMouseDrag ("mousemove")); - + /** * Resizes the peer canvas according to given area. * @@ -348,7 +351,6 @@ ctx.fillRect(0, 0, area.width, area.height); ctx.strokeStyle = "black"; ctx.strokeRect(0, 0, area.width, area.height); - } /** @@ -860,6 +862,20 @@ { return { "mouseenter" : true, "mouseleave" : true}; }; + + /** + * Invokes a mouse event listener of the target mouse event type. + * + * @param {String} mouseOp + * The mouse events name + * @param {MouseEvent} evt + * The raised mouse event + */ + this.handle = function(mouseOp, evt) + { + // no ops + }; + }; /** @@ -881,6 +897,9 @@ */ function MouseMovable(win, wid, x, y, width, height) { + /** Placeholder for the required mouse events listeners */ + var handlers = {}; + var mouseDrag = false; var ma = { "x" : x, "y" : y, "width" : width, "height" : height }; // register the listeners @@ -893,12 +912,12 @@ processMouseDragStop (this, "dblclick"), processMouseDragStart(this, "mousedown"), processMouseDragStop (this, "mouseup"), processMouseDrag (this, "mousemove"), processMouseDragStop (this, "mouseleave"), processMouseDragStop (this, "mouseout")]; - // win.canvas.addEventListener("drag", processMouseDrag(this, "drag")); - addListeners(win, mops, listeners); + + addListeners(handlers, mops, listeners); this.deregisterListeners = function() { - removeListeners(win, mops, listeners); + removeListeners(handlers, mops, listeners); }; this.getEvents = function() @@ -915,6 +934,23 @@ return events; }; + /** + * Invokes a mouse event listener of the target mouse event type. + * + * @param {String} mouseOp + * The mouse events name + * @param {MouseEvent} evt + * The raised mouse event + */ + this.handle = function(mouseOp, evt) + { + var listener = handlers[mouseOp]; + if (listener !== undefined) + { + listener(evt); + } + }; + function processMouseDragStop(mThis, mouseOp) { return function(evt) @@ -956,7 +992,7 @@ } var mousePos = win.getMousePos(evt); - + if (mousePos.x >= ma.x && mousePos.x <= ma.x + ma.width && mousePos.y >= ma.y && @@ -984,7 +1020,6 @@ { return; } - var mousePos = win.getMousePos(evt); var dx = evt.clientX - mThis.lastMouseEvent.clientX; @@ -1027,7 +1062,7 @@ * @param {Function} stateChangedCallback * A callback function for this window state change action. */ -function WindowStateChangedWorker(win, wid, x, y, width, height, stateChangedCallback) +function WindowStateChangedWorker(win, wid, x, y, width, height, stateChangedCallback, handlers) { var ma = { "x" : x, "y" : y, "width" : width, "height" : height }; var mops = ["dblclick", "click", "mousedown", "mouseup"]; @@ -1036,7 +1071,7 @@ { listeners[i] = processWindowState(this, mops[i]); } - addListeners(win, mops, listeners); + addListeners(handlers, mops, listeners); function processWindowState(mThis, mouseOp) { @@ -1048,7 +1083,7 @@ { return; } - + var mousePos = win.getMousePos(evt); if (mousePos.x >= ma.x && @@ -1057,7 +1092,6 @@ mousePos.y <= ma.y + ma.height) { stateChangedCallback(win, evt, mousePos, opCode); - evt.preventDefault(); } }; @@ -1070,7 +1104,7 @@ this.deregisterListeners = function() { - removeListeners(win, mops, listeners); + removeListeners(handlers, mops, listeners); }; }; @@ -1092,7 +1126,10 @@ */ function WindowClose(win, wid, x, y, width, height) { - this.wsc = new WindowStateChangedWorker(win, wid, x, y, width, height, windowCloseCallback); + /** Placeholder for the required mouse events listeners */ + var handlers = {}; + + this.wsc = new WindowStateChangedWorker(win, wid, x, y, width, height, windowCloseCallback, handlers); function windowCloseCallback(win, evt, mousePos, opCode) { @@ -1111,6 +1148,23 @@ { this.wsc.deregisterListeners(); }; + + /** + * Invokes a mouse event listener of the target mouse event type. + * + * @param {String} mouseOp + * The mouse events name + * @param {MouseEvent} evt + * The raised mouse event + */ + this.handle = function(mouseOp, evt) + { + var listener = handlers[mouseOp]; + if (listener !== undefined) + { + listener(evt); + } + }; }; /** @@ -1131,12 +1185,14 @@ */ function WindowIconify(win, wid, x, y, width, height) { - this.wsc = new WindowStateChangedWorker(win, wid, x, y, width, height, windowIconifyCallback); + /** Placeholder for the required mouse events listeners */ + var handlers = {}; + + this.wsc = new WindowStateChangedWorker(win, wid, x, y, width, height, windowIconifyCallback, handlers); function windowIconifyCallback(win, evt, mousePos, opCode) { win.iconify(); - p2j.socket.sendWindowIconState(win.id, true); }; @@ -1149,6 +1205,23 @@ { this.wsc.deregisterListeners(); }; + + /** + * Invokes a mouse event listener of the target mouse event type. + * + * @param {String} mouseOp + * The mouse events name + * @param {MouseEvent} evt + * The raised mouse event + */ + this.handle = function(mouseOp, evt) + { + var listener = handlers[mouseOp]; + if (listener !== undefined) + { + listener(evt); + } + }; }; /** @@ -1169,7 +1242,10 @@ */ function WindowMaximize(win, wid, x, y, width, height) { - this.wsc = new WindowStateChangedWorker(win, wid, x, y, width, height, windowMaximizeCallback); + /** Placeholder for the required mouse events listeners */ + var handlers = {}; + + this.wsc = new WindowStateChangedWorker(win, wid, x, y, width, height, windowMaximizeCallback, handlers); function windowMaximizeCallback(win, evt, mousePos, opCode) { @@ -1188,6 +1264,23 @@ { this.wsc.deregisterListeners(); }; + + /** + * Invokes a mouse event listener of the target mouse event type. + * + * @param {String} mouseOp + * The mouse events name + * @param {MouseEvent} evt + * The raised mouse event + */ + this.handle = function(mouseOp, evt) + { + var listener = handlers[mouseOp]; + if (listener !== undefined) + { + listener(evt); + } + }; }; /** @@ -1212,10 +1305,13 @@ */ function MousePopupable(win, wid, x, y, width, height, btnId) { + /** Placeholder for the required mouse events listeners */ + var handlers = {}; + var ma = { "x" : x, "y" : y, "width" : width, "height" : height }; var mops = ["click", "mousedown"]; var listeners = [processPopup(this, "click"), processPopup(this, "mousedown")]; - addListeners(win, mops, listeners); + addListeners(handlers, mops, listeners); function processPopup(mThis, mouseOp) { @@ -1247,13 +1343,30 @@ this.deregisterListeners = function() { - removeListeners(win, mops, listeners); + removeListeners(handlers, mops, listeners); }; this.getEvents = function() { return { "click" : true, "mouseDown" : true }; }; + + /** + * Invokes a mouse event listener of the target mouse event type. + * + * @param {String} mouseOp + * The mouse events name + * @param {MouseEvent} evt + * The raised mouse event + */ + this.handle = function(mouseOp, evt) + { + var listener = handlers[mouseOp]; + if (listener !== undefined) + { + listener(evt); + } + }; }; /** @@ -1282,35 +1395,35 @@ /** * Adds window events listeners. * - * @param {Window} win - * The window for which the target events listeners must be added. + * @param {Object} obj + * The place-holder of the target events listeners. * @param {Array} mops * The handled events. * @param {Array} listeners * The target listeners corresponding to their handled events */ -function addListeners(win, mops, listeners) +function addListeners(obj, mops, listeners) { for(var i = 0; i < listeners.length; i++) { - win.canvas.addEventListener(mops[i], listeners[i]); + obj[mops[i]] = listeners[i]; } } /** * Removes window events listeners. * - * @param {Window} win - * The window for which the target events handlers must be removed. + * @param {Object} obj + * The place-holder of the target events listeners. * @param {Array} mops * The handled events to remove. * @param {Array} listeners * The target listeners corresponding to their handled events */ -function removeListeners(win, mops, listeners) +function removeListeners(obj, mops, listeners) { for(var i = 0; i < listeners.length; i++) { - win.canvas.removeEventListener(mops[i], listeners[i]); + delete obj[mops[i]]; } } === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js' --- src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js 2016-04-15 07:35:01 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js 2016-04-19 19:49:14 +0000 @@ -45,7 +45,9 @@ ** the desktop background color and to notify the enclosed window about it, ** fixed TypedArray.slice is unsupported by IE. ** 011 HC 20160406 Overhaul of window-activation logic. -** 012 SBI 20160414 Fixed doWindowActivationChange(...) and activateTopVisibleWindow(...). +** 012 SBI 20160419 Fixed doWindowActivationChange(...) and activateTopVisibleWindow(...). Added +** p2j.screen.getEventTarget(evt), changed MouseEventDispatcher to deliver mouse +** events to the registered OS mouse widgets. */ "use strict"; @@ -223,9 +225,17 @@ */ me.globalCache = {}; + /** + * The mouse events global dispatcher. + */ var mouseEventDispatcher = new MouseEventDispatcher(); /** + * The global resize listener. + */ + var resizeHandler; + + /** * Dispatch mouse events to the registered widgets. */ function MouseEventDispatcher() @@ -235,13 +245,45 @@ var targetWidget; var targetWindow; var dragTimeout; - var downTimeStamp; - - document.addEventListener("mousedown", mouseDownHandler, false); - document.addEventListener("mouseup", mouseUpHandler, false); - document.addEventListener("mousemove", mouseMoveHandler, false); - document.addEventListener("click", mouseClickHandler, false); - + + document.addEventListener("mousedown", mouseDownHandler, false); + document.addEventListener("mouseup", mouseUpHandler, false); + document.addEventListener("mousemove", mouseMoveHandler, false); + document.addEventListener("click", mouseClickHandler, false); + + document.addEventListener("contextmenu", commonHandler, false); + document.addEventListener("dblclick" , commonHandler, false); + document.addEventListener("mouseenter", commonHandler, false); + document.addEventListener("mouseleave", commonHandler, false); + document.addEventListener("mouseover", commonHandler, false); + document.addEventListener("mouseout", commonHandler, false); + document.addEventListener("wheel", commonHandler, false); + document.addEventListener("drag", commonHandler, false); + + /** + * Dispatches a document widen events: "contextmenu", "dblclick", "mouseover", "mouseout", + * "mouseenter/mouseleave", "wheel", "drag" to the registered OS mouse widgets. + * + * @param {Event} evt + * The raised mouse event. + */ + function commonHandler(evt) + { + var mouseOp = evt.type; + + if (!down && !up) + { + targetWindow = p2j.screen.getEventTarget(evt); + } + + if (targetWindow === undefined) + { + return; + } + + dispatchEventToOSMouseWidgets(mouseOp, evt); + } + /** * Handles a document widen "mousedown" event. * @@ -251,13 +293,15 @@ function mouseDownHandler(evt) { down = true; - up = false; - downTimeStamp = Date.now(); - targetWindow = p2j.screen.topVisibleWindow(); + up = false; + + targetWindow = p2j.screen.getEventTarget(evt); + if (targetWindow !== undefined) { targetWidget = targetWindow.findMouseSource(evt, targetWindow.mouseAwareWidgets["mousedown"]); } + dispatchEvent("mousedown", evt); } @@ -269,7 +313,7 @@ */ function mouseUpHandler(evt) { - up = true; + up = true; down = false; dispatchEvent("mouseup", evt); } @@ -283,6 +327,7 @@ function mouseClickHandler(evt) { dispatchEvent("click", evt); + up = false; } /** @@ -297,7 +342,10 @@ { return; } + var mouseOp = evt.type; + dispatchEventToOSMouseWidgets(mouseOp, evt); + if (!dragTimeout) { //Sends drag notifications with the frequency that doesn't exceed one event per 100 ms. @@ -325,7 +373,15 @@ return; } + dispatchEventToOSMouseWidgets(mouseOp, evt); + + if (targetWidget === undefined) + { + return; + } + var mousePos = targetWindow.getMousePos(evt); + // check if targetWidget belongs to "any mouse" widgets (listen all events) // than sending mouseOp message is send to targetWidget if (!targetWindow.anyMouseAwareWidgets.hasOwnProperty(targetWidget)) @@ -333,10 +389,6 @@ dispatchEventToAnyMouseWidgets(mouseOp, evt, mousePos); } - if (targetWidget === undefined) - { - return; - } if (!targetWindow.processOsEvents || !p2j.screen.processMouse) { @@ -353,6 +405,42 @@ } /** + * Dispatches a mouse event to the registered OS mouse widgets. + * + * @param {String} mouseOp + * The mouse events name + * @param {MouseEvent} evt + * The raised mouse event + */ + function dispatchEventToOSMouseWidgets(mouseOp, evt) + { + if (targetWindow === undefined) + { + return; + } + + for (var osOp in targetWindow.osAwareWidgets) + { + if (targetWindow.osAwareWidgets.hasOwnProperty(osOp)) + { + var osWidgets = targetWindow.osAwareWidgets[osOp]; + for(var wid in osWidgets) + { + if (osWidgets.hasOwnProperty(wid)) + { + var osWidget = osWidgets[wid]; + if (evt.defaultPrevented) + { + return; + } + osWidget.handle(mouseOp, evt); + } + } + } + } + } + + /** * Dispatches event to any mouse widgets. * * @param {String} mouseOp @@ -2845,7 +2933,29 @@ return getWindow(wid); }; - /* + /** + * Get a target window that is a target for the received mouse event. + * + * @param evt + * The received mouse event. + * + * @return The window instance if there is a window that is a target for the received event, + * otherwise undefined. + */ + me.getEventTarget = function(evt) + { + var el = evt.target; + if (el.id && el.id.indexOf("pwindow_") == 0) + { + var id = parseInt(el.id.substring(8)); + + return getWindow(id); + } + + return undefined; + }; + + /** * Retrieve the current font used to draw text. * * @return See above. @@ -3062,7 +3172,7 @@ // register listener for window resize; this is added to the document, to allow event // notification during mouse drag even if mouse is outside of the window - var resizeHandler = new MouseResizeable(); + resizeHandler = new MouseResizeable(); } };