=== modified file 'src/com/goldencode/p2j/ui/client/TopLevelWindow.java' --- src/com/goldencode/p2j/ui/client/TopLevelWindow.java 2016-03-07 12:46:23 +0000 +++ src/com/goldencode/p2j/ui/client/TopLevelWindow.java 2016-03-10 23:39:36 +0000 @@ -37,6 +37,7 @@ ** 014 EVL 20160224 Javadoc fixes to make compatible with Oracle Java 8 for Solaris 10. ** 015 HC 20160304 Replaced Window.moveBy() with setPhysicalLocation(). ** 016 VIG 20160307 Moved system menus here from WindowGuiImpl, moved init* and create* methods. +** SBI 20160310 Changed to reuse the common code */ package com.goldencode.p2j.ui.client; @@ -44,6 +45,7 @@ import java.awt.event.*; import java.io.*; import java.util.*; +import java.util.function.Predicate; import com.goldencode.p2j.ui.*; import com.goldencode.p2j.ui.chui.*; @@ -812,19 +814,18 @@ if (mouseSource != null && mouseSource.isDisplayed()) { - WidgetId id = null; - // search for a parent with a valid id - Widget parent = mouseSource; - while (parent != null) + Widget parent = WidgetRegistry.findAncestor(mouseSource, new Predicate() { - id = parent.getId(); - if (id != null) + @Override + public boolean test(Widget t) { - break; + return UiUtils.getWidgetId(t) != null; } - parent = parent.parent(); - } + }); + + WidgetId id = (parent != null) ? parent.getId() : null; + if (id != null) { // not all OS-widgets have an ID, skip those === modified file 'src/com/goldencode/p2j/ui/client/gui/EditorGuiImpl.java' --- src/com/goldencode/p2j/ui/client/gui/EditorGuiImpl.java 2016-03-10 10:52:08 +0000 +++ src/com/goldencode/p2j/ui/client/gui/EditorGuiImpl.java 2016-03-10 23:38:49 +0000 @@ -972,13 +972,18 @@ else { TopLevelWindow wnd = topLevelWindow(); + if (wnd != null) { - String selection = getSelectedText(); - boolean selectionEmpty = selection == null || selection.isEmpty(); - Menu menu = wnd.initEditorPopup(this, e, selectionEmpty); - ((EditorPopupGuiImpl) menu).initEditorItems(selectionEmpty); - Menu.showPopupMenu(menu, this); + NativePoint origin = editor.screenPhysicalLocation(); + if (editor.physicalBounds().contains(e.getX() - origin.x, e.getY() - origin.y)) + { + String selection = getSelectedText(); + boolean selectionEmpty = selection == null || selection.isEmpty(); + Menu menu = wnd.initEditorPopup(this, e, selectionEmpty); + ((EditorPopupGuiImpl) menu).initEditorItems(selectionEmpty); + Menu.showPopupMenu(menu, this); + } } } } === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/swing/SwingMouseHandler.java' --- src/com/goldencode/p2j/ui/client/gui/driver/swing/SwingMouseHandler.java 2016-03-10 10:52:08 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/swing/SwingMouseHandler.java 2016-03-10 23:40:45 +0000 @@ -18,8 +18,8 @@ ** window. ** 003 HC 20151013 NPE fix. ** 004 HC 20151024 Fixed race condition when dispatching mouse events. -** 005 SBI 20160307 Changed processAction to deliver mouse events to the closest registered widget -** in the source mouse widget parent's hierarchy. +** 005 SBI 20160310 Changed processAction/findMouseSource to deliver mouse events to the closest +** registered widget in the source mouse widget parent's hierarchy. */ package com.goldencode.p2j.ui.client.gui.driver.swing; @@ -37,6 +37,8 @@ import com.goldencode.p2j.ui.WidgetId; import com.goldencode.p2j.ui.client.*; import com.goldencode.p2j.ui.client.event.*; +import com.goldencode.p2j.ui.client.gui.EditorGuiImpl; +import com.goldencode.p2j.ui.client.gui.LabelGuiImpl; import com.goldencode.p2j.ui.client.gui.ScrollBarGuiImpl; import com.goldencode.p2j.ui.client.gui.ScrollPaneGuiImpl; import com.goldencode.p2j.ui.client.gui.driver.*; @@ -286,7 +288,7 @@ { Widget mouseSource = findMouseSource(e); // if the widget has changed, send EXITED/ENTERED events - if (lastHoveredWidget != null && lastHoveredWidget != mouseSource) + if (lastHoveredWidget != null && !lastHoveredWidget.getActualBounds().contains(e.getX(), e.getY())) { MouseEvent exite = new MouseEvent((Component) e.getSource(), MouseEvent.MOUSE_EXITED, @@ -301,7 +303,11 @@ processAction(lastHoveredWidget, exite); // call this unconditionally, as the widget needs to be notified that it was exit... tc.postMouseEvent(exite, ews.getWindowId(), UiUtils.getWidgetIdAsInt(lastHoveredWidget)); - + lastHoveredWidget = null; + } + if (lastHoveredWidget != mouseSource + && mouseSource!= null && mouseSource.getActualBounds().contains(e.getX(), e.getY())) + { MouseEvent entere = new MouseEvent((Component) e.getSource(), MouseEvent.MOUSE_ENTERED, e.getWhen(), @@ -381,7 +387,43 @@ Widget mouseSource = window.findMouseSource(new MouseEvt(e, window)); - return mouseSource; + // find widget in its ancestor's hierarchy that has an id + Widget parent = WidgetRegistry.findAncestor(mouseSource, new Predicate() + { + @Override + public boolean test(Widget t) + { + // TODO: to improve/simplify the mouse pointer is over a widget + // work around to skip labels + return UiUtils.getWidgetId(t) != null && !(LabelGuiImpl.class.equals(t.getClass())); + } + }); + + // TODO: move this widget-specific logic into methods that are implemented in the widget + // hierarchy so that we do not have direct references to widget classes in this common code + + // if it is scroll bar or scroll button, then find its scroll pane parent + if (parent instanceof ScrollBarGuiImpl || + (parent instanceof Button && parent.parent() instanceof ScrollBarGuiImpl)) + { + parent = WidgetRegistry.findAncestor(parent, new Predicate() + { + @Override + public boolean test(Widget t) + { + return ScrollPaneGuiImpl.class.equals(t.getClass()); + } + }); + } + + // TODO: move this widget-specific logic into methods that are implemented in the widget + // hierarchy so that we do not have direct references to widget classes in this common code + if (parent instanceof ScrollPaneGuiImpl && parent.parent() instanceof EditorGuiImpl) + { + parent = parent.parent(); + } + + return parent; } /** @@ -421,33 +463,8 @@ return false; } - // find widget in its ancestor's hierarchy that has an id - Widget parent = WidgetRegistry.findAncestor(widget, new Predicate() - { - @Override - public boolean test(Widget t) - { - return UiUtils.getWidgetId(t) != null; - } - }); - - // TODO: move this widget-specific logic into methods that are implemented in the widget - // hierarchy so that we do not have direct references to widget classes in this common code - - // if it is scroll bar then find its scroll pane parent - if (parent instanceof ScrollBarGuiImpl) - { - parent = WidgetRegistry.findAncestor(parent, new Predicate() - { - @Override - public boolean test(Widget t) - { - return ScrollPaneGuiImpl.class.equals(t.getClass()); - } - }); - } - - WidgetId wid = UiUtils.getWidgetId(parent); + + WidgetId wid = UiUtils.getWidgetId(widget); if (wid == null) { === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/WebMouseHandler.java' --- src/com/goldencode/p2j/ui/client/gui/driver/web/WebMouseHandler.java 2016-03-10 10:52:08 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/web/WebMouseHandler.java 2016-03-10 22:29:02 +0000 @@ -14,6 +14,7 @@ ** 003 SBI 20151201 Fixed to deliver mouse events to their target widgets (JS client has ** no information about child-parent relations, only widgets z-order.) ** 004 IAS 20160229 Changed first argument for the WidgetRegistry.findAncestor() call +** 005 SBI 20160104 Fixed the cursor positioning within the editor. */ package com.goldencode.p2j.ui.client.gui.driver.web; @@ -53,7 +54,8 @@ Widget w = tc.getWidget(widgetId); if (w instanceof AbstractContainer) { - NativePoint origin = w.displayPhysicalLocation(); + // It needs to get the widget's location with respect to the parent window. + NativePoint origin = w.screenPhysicalLocation(); Widget target = ((AbstractContainer) w).findMouseSource( new NativePoint(event.getX() - origin.x, event.getY() - origin.y)); === 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-03-09 16:03:40 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.mouse.js 2016-03-10 21:26:14 +0000 @@ -19,6 +19,7 @@ ** early incorrect dismiss, no need to attach focus listener to click if we ** already have it for press. This confuses the overlay window. ** 006 IAS 20160217 LOAD-MOUSE-POINTER ans SET-WAIT-STATE support +** 007 SBI 20160310 Added getEvents() to MouseMovable. **/ "use strict";