diff options
author | Denis Anisimov <denis@vaadin.com> | 2016-11-23 20:11:33 +0300 |
---|---|---|
committer | Denis Anisimov <denis@vaadin.com> | 2016-11-29 16:03:31 +0300 |
commit | 8ba529503b6caee2d7755f292fb1f9f985943e78 (patch) | |
tree | a84eae038a6f6944947835ac5e121decaef0927b /client/src | |
parent | d2ce5362fffe4d85b95762a02f5e68a980af7789 (diff) | |
download | vaadin-framework-8ba529503b6caee2d7755f292fb1f9f985943e78.tar.gz vaadin-framework-8ba529503b6caee2d7755f292fb1f9f985943e78.zip |
Provide access to window order position in windows stack (#14325).
Change-Id: I259c659987b5b15b354e16d0be1523f4ede809f0
Diffstat (limited to 'client/src')
5 files changed, 260 insertions, 12 deletions
diff --git a/client/src/main/java/com/vaadin/client/ui/VWindow.java b/client/src/main/java/com/vaadin/client/ui/VWindow.java index 8f1292ca1d..5a316933ff 100644 --- a/client/src/main/java/com/vaadin/client/ui/VWindow.java +++ b/client/src/main/java/com/vaadin/client/ui/VWindow.java @@ -44,6 +44,7 @@ import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.dom.client.ScrollEvent; import com.google.gwt.event.dom.client.ScrollHandler; +import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; @@ -64,6 +65,8 @@ import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; import com.vaadin.client.ui.aria.AriaHelper; import com.vaadin.client.ui.window.WindowMoveEvent; import com.vaadin.client.ui.window.WindowMoveHandler; +import com.vaadin.client.ui.window.WindowOrderEvent; +import com.vaadin.client.ui.window.WindowOrderHandler; import com.vaadin.shared.Connector; import com.vaadin.shared.EventId; import com.vaadin.shared.ui.window.WindowMode; @@ -79,6 +82,9 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, private static ArrayList<VWindow> windowOrder = new ArrayList<>(); + private static HandlerManager WINDOW_ORDER_HANDLER = new HandlerManager( + VWindow.class); + private static boolean orderingDefered; public static final String CLASSNAME = "v-window"; @@ -278,14 +284,37 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, } public void bringToFront() { - int curIndex = windowOrder.indexOf(this); + bringToFront(true); + } + + private void bringToFront(boolean notifyListeners) { + int curIndex = getWindowOrder(); if (curIndex + 1 < windowOrder.size()) { windowOrder.remove(this); windowOrder.add(this); for (; curIndex < windowOrder.size(); curIndex++) { - windowOrder.get(curIndex).setWindowOrder(curIndex); + VWindow window = windowOrder.get(curIndex); + window.setWindowOrder(curIndex); } } + if (notifyListeners) { + fireOrderEvent(); + } + } + + static void fireOrderEvent() { + fireOrderEvent(windowOrder); + } + + private void doFireOrderEvent() { + ArrayList<VWindow> list = new ArrayList<>(); + list.add(this); + fireOrderEvent(list); + } + + private static void fireOrderEvent(ArrayList<VWindow> windows) { + WINDOW_ORDER_HANDLER + .fireEvent(new WindowOrderEvent(new ArrayList<>(windows))); } /** @@ -317,13 +346,22 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, windowOrder.add(this); setPopupPosition(order * STACKING_OFFSET_PIXELS, order * STACKING_OFFSET_PIXELS); - + doFireOrderEvent(); } private void setWindowOrder(int order) { setZIndex(order + Z_INDEX); } + /** + * Returns window position in list of opened and shown windows. + * + * @since 8.0.0 + */ + public final int getWindowOrder() { + return windowOrder.indexOf(this); + } + @Override protected void setZIndex(int zIndex) { super.setZIndex(zIndex); @@ -536,7 +574,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, for (int i = 0; i < array.length; i++) { VWindow w = array[i]; if (w.bringToFrontSequence != -1 || w.vaadinModality) { - w.bringToFront(); + w.bringToFront(false); w.bringToFrontSequence = -1; } } @@ -548,6 +586,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, if (topmost != null && topmost.vaadinModality) { topmost.focus(); } + fireOrderEvent(); } @Override @@ -655,15 +694,21 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, } super.hide(); - int curIndex = windowOrder.indexOf(this); + int curIndex = getWindowOrder(); // Remove window from windowOrder to avoid references being left // hanging. windowOrder.remove(curIndex); // Update the z-indices of any remaining windows + ArrayList<VWindow> update = new ArrayList<>( + windowOrder.size() - curIndex + 1); + update.add(this); while (curIndex < windowOrder.size()) { - windowOrder.get(curIndex).setWindowOrder(curIndex++); + VWindow window = windowOrder.get(curIndex); + window.setWindowOrder(curIndex++); + update.add(window); } focusTopmostModalWindow(); + fireOrderEvent(update); } /** For internal use only. May be removed or replaced in the future. */ @@ -689,8 +734,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, } private void showModalityCurtain() { - getModalityCurtain().getStyle() - .setZIndex(windowOrder.indexOf(this) + Z_INDEX); + getModalityCurtain().getStyle().setZIndex(getWindowOrder() + Z_INDEX); if (isShowing()) { getOverlayContainer().insertBefore(getModalityCurtain(), @@ -1463,4 +1507,16 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, return addHandler(handler, WindowMoveEvent.getType()); } + /** + * Adds a Handler for window order change event. + * + * @since 8.0.0 + * + * @return registration object to deregister the handler + */ + public static HandlerRegistration addWindowOrderHandler( + WindowOrderHandler handler) { + return WINDOW_ORDER_HANDLER.addHandler(WindowOrderEvent.getType(), + handler); + } } diff --git a/client/src/main/java/com/vaadin/client/ui/ui/UIConnector.java b/client/src/main/java/com/vaadin/client/ui/ui/UIConnector.java index af212c16f4..677abbbecb 100644 --- a/client/src/main/java/com/vaadin/client/ui/ui/UIConnector.java +++ b/client/src/main/java/com/vaadin/client/ui/ui/UIConnector.java @@ -16,6 +16,11 @@ package com.vaadin.client.ui.ui; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.logging.Logger; @@ -75,14 +80,19 @@ import com.vaadin.client.ui.VUI; import com.vaadin.client.ui.VWindow; import com.vaadin.client.ui.layout.MayScrollChildren; import com.vaadin.client.ui.window.WindowConnector; +import com.vaadin.client.ui.window.WindowOrderEvent; +import com.vaadin.client.ui.window.WindowOrderHandler; import com.vaadin.server.Page.Styles; import com.vaadin.shared.ApplicationConstants; +import com.vaadin.shared.Connector; +import com.vaadin.shared.EventId; import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.Version; import com.vaadin.shared.communication.MethodInvocation; import com.vaadin.shared.ui.ComponentStateUtil; import com.vaadin.shared.ui.Connect; import com.vaadin.shared.ui.Connect.LoadStyle; +import com.vaadin.shared.ui.WindowOrderRpc; import com.vaadin.shared.ui.ui.DebugWindowClientRpc; import com.vaadin.shared.ui.ui.DebugWindowServerRpc; import com.vaadin.shared.ui.ui.PageClientRpc; @@ -103,6 +113,8 @@ public class UIConnector extends AbstractSingleComponentContainerConnector private String activeTheme = null; + private HandlerRegistration windowOrderRegistration; + private final StateChangeHandler childStateChangeHandler = new StateChangeHandler() { @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { @@ -112,9 +124,33 @@ public class UIConnector extends AbstractSingleComponentContainerConnector } }; + private WindowOrderHandler windowOrderHandler = new WindowOrderHandler() { + + @Override + public void onWindowOrderChange(WindowOrderEvent event) { + VWindow[] windows = event.getWindows(); + HashMap<Integer, Connector> orders = new HashMap<>(); + boolean hasEventListener = hasEventListener(EventId.WINDOW_ORDER); + for (VWindow window : windows) { + Connector connector = Util.findConnectorFor(window); + orders.put(window.getWindowOrder(), connector); + if (connector instanceof AbstractConnector + && ((AbstractConnector) connector) + .hasEventListener(EventId.WINDOW_ORDER)) { + hasEventListener = true; + } + } + if (hasEventListener) { + getRpcProxy(WindowOrderRpc.class).windowOrderChanged(orders); + } + } + }; + @Override protected void init() { super.init(); + windowOrderRegistration = VWindow + .addWindowOrderHandler(windowOrderHandler); registerRpc(PageClientRpc.class, new PageClientRpc() { @Override @@ -703,6 +739,8 @@ public class UIConnector extends AbstractSingleComponentContainerConnector } } + setWindowOrderAndPosition(); + // Close removed sub windows for (ComponentConnector c : event.getOldChildren()) { if (c.getParent() != this && c instanceof WindowConnector) { @@ -1124,4 +1162,50 @@ public class UIConnector extends AbstractSingleComponentContainerConnector getRpcProxy(UIServerRpc.class).acknowledge(); } + + private void setWindowOrderAndPosition() { + if (windowOrderRegistration != null) { + windowOrderRegistration.removeHandler(); + } + WindowOrderCollector collector = new WindowOrderCollector(); + HandlerRegistration registration = VWindow + .addWindowOrderHandler(collector); + for (ComponentConnector c : getChildComponents()) { + if (c instanceof WindowConnector) { + WindowConnector wc = (WindowConnector) c; + wc.setWindowOrderAndPosition(); + } + } + windowOrderHandler.onWindowOrderChange( + new WindowOrderEvent(collector.getWindows())); + registration.removeHandler(); + windowOrderRegistration = VWindow + .addWindowOrderHandler(windowOrderHandler); + } + + private static class WindowOrderCollector + implements WindowOrderHandler, Comparator<VWindow> { + + private HashSet<VWindow> windows = new HashSet<>(); + + @Override + public void onWindowOrderChange(WindowOrderEvent event) { + windows.addAll(Arrays.asList(event.getWindows())); + } + + @Override + public int compare(VWindow window1, VWindow window2) { + if (window1.getWindowOrder() == window2.getWindowOrder()) { + return 0; + } + return window1.getWindowOrder() > window2.getWindowOrder() ? 1 : -1; + } + + ArrayList<VWindow> getWindows() { + ArrayList<VWindow> result = new ArrayList<>(); + result.addAll(windows); + Collections.sort(result, this); + return result; + } + }; } diff --git a/client/src/main/java/com/vaadin/client/ui/window/WindowConnector.java b/client/src/main/java/com/vaadin/client/ui/window/WindowConnector.java index 3d5d7bbcfd..4e28fb6349 100644 --- a/client/src/main/java/com/vaadin/client/ui/window/WindowConnector.java +++ b/client/src/main/java/com/vaadin/client/ui/window/WindowConnector.java @@ -38,7 +38,6 @@ import com.vaadin.client.ConnectorHierarchyChangeEvent; import com.vaadin.client.LayoutManager; import com.vaadin.client.Paintable; import com.vaadin.client.UIDL; -import com.vaadin.client.communication.RpcProxy; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.ui.AbstractSingleComponentContainerConnector; import com.vaadin.client.ui.ClickEventHandler; @@ -497,8 +496,7 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector @Override public void onWindowMove(WindowMoveEvent event) { - RpcProxy.create(WindowServerRpc.class, this) - .windowMoved(event.getNewX(), event.getNewY()); - + getRpcProxy(WindowServerRpc.class).windowMoved(event.getNewX(), + event.getNewY()); } } diff --git a/client/src/main/java/com/vaadin/client/ui/window/WindowOrderEvent.java b/client/src/main/java/com/vaadin/client/ui/window/WindowOrderEvent.java new file mode 100644 index 0000000000..33517462ea --- /dev/null +++ b/client/src/main/java/com/vaadin/client/ui/window/WindowOrderEvent.java @@ -0,0 +1,74 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.ui.window; + +import java.util.ArrayList; + +import com.google.gwt.event.shared.GwtEvent; +import com.vaadin.client.ui.VWindow; + +/** + * Event for window order position updates. + * + * @since 8.0.0 + * + * @author Vaadin Ltd + */ +public class WindowOrderEvent extends GwtEvent<WindowOrderHandler> { + + private static final Type<WindowOrderHandler> TYPE = new Type<>(); + + private final ArrayList<VWindow> windows; + + /** + * Creates a new event with the given order. + * + * @param windows + * The new order position for the VWindow + */ + public WindowOrderEvent(ArrayList<VWindow> windows) { + this.windows = windows; + } + + @Override + public Type<WindowOrderHandler> getAssociatedType() { + return TYPE; + } + + /** + * Returns windows in order. + * + * @return windows in the specific order + */ + public VWindow[] getWindows() { + return windows.toArray(new VWindow[windows.size()]); + } + + @Override + protected void dispatch(WindowOrderHandler handler) { + handler.onWindowOrderChange(this); + } + + /** + * Gets the type of the event. + * + * @return the type of the event + */ + public static Type<WindowOrderHandler> getType() { + return TYPE; + } + +} diff --git a/client/src/main/java/com/vaadin/client/ui/window/WindowOrderHandler.java b/client/src/main/java/com/vaadin/client/ui/window/WindowOrderHandler.java new file mode 100644 index 0000000000..3a492ef27e --- /dev/null +++ b/client/src/main/java/com/vaadin/client/ui/window/WindowOrderHandler.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.ui.window; + +import com.google.gwt.event.shared.EventHandler; + +/** + * Handler for {@link WindowOrderEvent}s. + * + * @since 8.0.0 + * + * @author Vaadin Ltd + */ +public interface WindowOrderHandler extends EventHandler { + + /** + * Called when the VWindow instances changed their order position. + * + * @param event + * Contains windows whose position has changed + */ + public void onWindowOrderChange(WindowOrderEvent event); +}
\ No newline at end of file |