Add a glass panel to the root when moving the splitter in a
SplitLayoutPanel so that it catches mouse events over an iframe
correctly. (This is just copied from the implementation in SplitPanel).
Review by: jlabanca@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9194 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/SplitLayoutPanel.java b/user/src/com/google/gwt/user/client/ui/SplitLayoutPanel.java
index 6997d1d..e34870e 100644
--- a/user/src/com/google/gwt/user/client/ui/SplitLayoutPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/SplitLayoutPanel.java
@@ -1,12 +1,12 @@
/*
* Copyright 2009 Google Inc.
- *
+ *
* 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
@@ -18,6 +18,8 @@
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Event;
@@ -25,19 +27,19 @@
/**
* A panel that adds user-positioned splitters between each of its child
* widgets.
- *
+ *
* <p>
* This panel is used in the same way as {@link DockLayoutPanel}, except that
* its children's sizes are always specified in {@link Unit#PX} units, and each
* pair of child widgets has a splitter between them that the user can drag.
* </p>
- *
+ *
* <p>
* This widget will <em>only</em> work in standards mode, which requires that
* the HTML page in which it is run have an explicit <!DOCTYPE>
* declaration.
* </p>
- *
+ *
* <h3>CSS Style Rules</h3>
* <ul class='css'>
* <li>.gwt-SplitLayoutPanel { the panel itself }</li>
@@ -46,7 +48,7 @@
* <li>.gwt-SplitLayoutPanel .gwt-SplitLayoutPanel-VDragger { vertical dragger }
* </li>
* </ul>
- *
+ *
* <p>
* <h3>Example</h3>
* {@example com.google.gwt.examples.SplitLayoutPanelExample}
@@ -106,6 +108,14 @@
switch (event.getTypeInt()) {
case Event.ONMOUSEDOWN:
mouseDown = true;
+
+ // Resize glassElem to take up the entire scrollable window area
+ int height = RootLayoutPanel.get().getElement().getScrollHeight() - 1;
+ int width = RootLayoutPanel.get().getElement().getScrollWidth() - 1;
+ glassElem.getStyle().setHeight(height, Unit.PX);
+ glassElem.getStyle().setWidth(width, Unit.PX);
+ Document.get().getBody().appendChild(glassElem);
+
offset = getEventPosition(event) - getAbsolutePosition();
Event.setCapture(getElement());
event.preventDefault();
@@ -113,6 +123,9 @@
case Event.ONMOUSEUP:
mouseDown = false;
+
+ glassElem.removeFromParent();
+
Event.releaseCapture(getElement());
event.preventDefault();
break;
@@ -206,7 +219,13 @@
private static final int DEFAULT_SPLITTER_SIZE = 8;
- private final int splitterSize;
+ private final int splitterSize;
+
+ /**
+ * The element that masks the screen so we can catch mouse events over
+ * iframes.
+ */
+ private static Element glassElem = null;
/**
* Construct a new {@link SplitLayoutPanel} with the default splitter size of
@@ -219,18 +238,34 @@
/**
* Construct a new {@link SplitLayoutPanel} with the specified splitter size
* in pixels.
- *
+ *
* @param splitterSize the size of the splitter in pixels
*/
public SplitLayoutPanel(int splitterSize) {
super(Unit.PX);
this.splitterSize = splitterSize;
setStyleName("gwt-SplitLayoutPanel");
+
+ if (glassElem == null) {
+ glassElem = Document.get().createDivElement();
+ glassElem.getStyle().setPosition(Position.ABSOLUTE);
+ glassElem.getStyle().setTop(0, Unit.PX);
+ glassElem.getStyle().setLeft(0, Unit.PX);
+ glassElem.getStyle().setMargin(0, Unit.PX);
+ glassElem.getStyle().setPadding(0, Unit.PX);
+ glassElem.getStyle().setBorderWidth(0, Unit.PX);
+
+ // We need to set the background color or mouse events will go right
+ // through the glassElem. If the SplitPanel contains an iframe, the
+ // iframe will capture the event and the slider will stop moving.
+ glassElem.getStyle().setProperty("background", "white");
+ glassElem.getStyle().setOpacity(0.0);
+ }
}
/**
* Return the size of the splitter in pixels.
- *
+ *
* @return the splitter size
*/
public int getSplitterSize() {
@@ -264,20 +299,20 @@
/**
* Sets the minimum allowable size for the given widget.
- *
+ *
* <p>
* Its associated splitter cannot be dragged to a position that would make it
* smaller than this size. This method has no effect for the
* {@link DockLayoutPanel.Direction#CENTER} widget.
* </p>
- *
+ *
* @param child the child whose minimum size will be set
* @param minSize the minimum size for this widget
*/
public void setWidgetMinSize(Widget child, int minSize) {
assertIsChild(child);
Splitter splitter = getAssociatedSplitter(child);
- // The splitter is null for the center element.
+ // The splitter is null for the center element.
if (splitter != null) {
splitter.setMinSize(minSize);
}