/**
* Copyright 2008 - 2015 The Loon Game Engine Authors
*
* 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.
*
* @project loon
* @author cping
* @email:javachenpeng@yahoo.com
* @version 0.5
*/
package loon.html5.gwt.widgets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
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.Timer;
import com.google.gwt.user.client.Window;
public class ResizableWidgetCollection implements ResizeHandler,
Iterable<ResizableWidget> {
static class ResizableWidgetInfo {
private ResizableWidget widget;
private int curOffsetHeight = 0;
private int curOffsetWidth = 0;
private int curClientHeight = 0;
private int curClientWidth = 0;
public ResizableWidgetInfo(ResizableWidget widget) {
this.widget = widget;
updateSizes();
}
public int getClientHeight() {
return curClientHeight;
}
public int getClientWidth() {
return curClientWidth;
}
public int getOffsetHeight() {
return curOffsetHeight;
}
public int getOffsetWidth() {
return curOffsetWidth;
}
public boolean updateSizes() {
int offsetWidth = widget.getElement().getOffsetWidth();
int offsetHeight = widget.getElement().getOffsetHeight();
int clientWidth = widget.getElement().getClientWidth();
int clientHeight = widget.getElement().getClientHeight();
if (offsetWidth != curOffsetWidth
|| offsetHeight != curOffsetHeight
|| clientWidth != curClientWidth
|| clientHeight != curClientHeight) {
this.curOffsetWidth = offsetWidth;
this.curOffsetHeight = offsetHeight;
this.curClientWidth = clientWidth;
this.curClientHeight = clientHeight;
return true;
}
return false;
}
}
private static final int DEFAULT_RESIZE_CHECK_DELAY = 400;
private static ResizableWidgetCollection staticCollection = null;
public static ResizableWidgetCollection get() {
if (staticCollection == null) {
staticCollection = new ResizableWidgetCollection();
}
return staticCollection;
}
private Timer resizeCheckTimer = new Timer() {
@Override
public void run() {
if (windowHeight != Window.getClientHeight()
|| windowWidth != Window.getClientWidth()) {
windowHeight = Window.getClientHeight();
windowWidth = Window.getClientWidth();
schedule(resizeCheckDelay);
return;
}
checkWidgetSize();
if (resizeCheckingEnabled) {
schedule(resizeCheckDelay);
}
}
};
private Map<ResizableWidget, ResizableWidgetInfo> widgets = new HashMap<ResizableWidget, ResizableWidgetInfo>();
int windowHeight = 0;
int windowWidth = 0;
private HandlerRegistration windowHandler;
int resizeCheckDelay = DEFAULT_RESIZE_CHECK_DELAY;
boolean resizeCheckingEnabled;
public ResizableWidgetCollection() {
this(DEFAULT_RESIZE_CHECK_DELAY);
}
public ResizableWidgetCollection(boolean resizeCheckingEnabled) {
this(DEFAULT_RESIZE_CHECK_DELAY, resizeCheckingEnabled);
}
public ResizableWidgetCollection(int resizeCheckDelay) {
this(resizeCheckDelay, true);
}
protected ResizableWidgetCollection(int resizeCheckDelay,
boolean resizeCheckingEnabled) {
setResizeCheckDelay(resizeCheckDelay);
setResizeCheckingEnabled(resizeCheckingEnabled);
}
public void add(ResizableWidget widget) {
widgets.put(widget, new ResizableWidgetInfo(widget));
}
public void checkWidgetSize() {
for (Map.Entry<ResizableWidget, ResizableWidgetInfo> entry : widgets
.entrySet()) {
ResizableWidget widget = entry.getKey();
ResizableWidgetInfo info = entry.getValue();
if (info.updateSizes()) {
if (info.getOffsetWidth() > 0 && info.getOffsetHeight() > 0
&& widget.isAttached()) {
widget.onResize(info.getOffsetWidth(),
info.getOffsetHeight());
}
}
}
}
public int getResizeCheckDelay() {
return resizeCheckDelay;
}
public boolean isResizeCheckingEnabled() {
return resizeCheckingEnabled;
}
public Iterator<ResizableWidget> iterator() {
return widgets.keySet().iterator();
}
public void remove(ResizableWidget widget) {
widgets.remove(widget);
}
public void setResizeCheckDelay(int resizeCheckDelay) {
this.resizeCheckDelay = resizeCheckDelay;
}
public void setResizeCheckingEnabled(boolean enabled) {
if (enabled && !resizeCheckingEnabled) {
resizeCheckingEnabled = true;
if (windowHandler == null) {
windowHandler = Window.addResizeHandler(this);
}
resizeCheckTimer.schedule(resizeCheckDelay);
} else if (!enabled && resizeCheckingEnabled) {
resizeCheckingEnabled = false;
if (windowHandler != null) {
windowHandler.removeHandler();
windowHandler = null;
}
resizeCheckTimer.cancel();
}
}
public void updateWidgetSize(ResizableWidget widget) {
if (!widget.isAttached()) {
return;
}
ResizableWidgetInfo info = widgets.get(widget);
if (info != null) {
info.updateSizes();
}
}
@Override
public void onResize(ResizeEvent event) {
checkWidgetSize();
}
}