If you want a large modal PopupPanel, you are in trouble as the browser 
scroll bars are disabled.

Solution 1:  Wrap the contents of the PopupPanel in a scroll pane.
Problem: Looks horrible, as there are now scroll bars on the browser, and in 
the PopupPanel.  There is also a problem with the mouse scroll wheel causing 
scrolling outside the scroll pane.

Solution 2:  Allow the PopupPanel to be non modal with glass enabled. Ie: 
setModal(false), setGlassEnabled(true).
Problem: User can tab out of the PopupPanel and start modifying values 
behind it.

...and yet anther problem with modal PopupPanels, you can use the mouse 
scroll wheel to scroll it out of view, however, once it goes out of view, 
the scroll wheel no longer works, and you can't get it back!

What we need is a modal PopupPanel that allows scrolling, but nothing else!

Here is my attempt, it's a little hacky, but seems to work.  Has anyone else 
tried to create large PopupPanels?

Cheers.

import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.ScrollEvent;
import com.google.gwt.user.client.Window.ScrollHandler;
import com.google.gwt.user.client.ui.PopupPanel;

/**
 * A popup panel that will center itself upon page scroll or resize.
 * This popup panel will be modal, however, will allow scrolling.
 * 
 * @author Craig Mitchell
 * @since 05/04/2011
 */
public class CenteredPopupPanel extends PopupPanel {

public CenteredPopupPanel() {
super();
 // Listen for a scroll
final HandlerRegistration windowScrollHandler = 
Window.addWindowScrollHandler(new ScrollHandler() {
public void onWindowScroll(ScrollEvent event) {
// Only move the panel if it is visible, and it isn't larger then the 
browser
if (CenteredPopupPanel.this.isVisible()
&& Window.getClientHeight() > CenteredPopupPanel.this.getOffsetHeight()
&& Window.getClientWidth() > CenteredPopupPanel.this.getOffsetWidth()) {
CenteredPopupPanel.this.center();
}
}
});
 // Listen for a resize
final HandlerRegistration windowResizeHandler = Window.addResizeHandler(new 
ResizeHandler() {
public void onResize(ResizeEvent event) {
// Only move the panel if it is visible, and it isn't larger then the 
browser
if (CenteredPopupPanel.this.isVisible()
&& Window.getClientHeight() > CenteredPopupPanel.this.getOffsetHeight()
&& Window.getClientWidth() > CenteredPopupPanel.this.getOffsetWidth()) {
CenteredPopupPanel.this.center();
}
}
});
 // Remove handlers on close
this.addCloseHandler(new CloseHandler<PopupPanel>() {
public void onClose(CloseEvent<PopupPanel> event) {
windowScrollHandler.removeHandler();
windowResizeHandler.removeHandler();
}
});
}
 @Override
public void center() {
super.center();
 // If the popup panel is too big for the browser, scroll the browser to the 
top of the popup panel
if (Window.getClientHeight() < CenteredPopupPanel.this.getOffsetHeight()) {
Window.scrollTo(Window.getScrollLeft(), this.getAbsoluteTop());
}
}

@Override
protected void onPreviewNativeEvent(NativePreviewEvent event) {
// Allow mouse events to be non modal (which will allow scrolling)
if (event.getNativeEvent().getType().indexOf("mouse") != -1) {
setModal(false);
}
// Everything else is modal
else {
setModal(true);
}
super.onPreviewNativeEvent(event);
}
}

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en.

Reply via email to