| /* |
| * Copyright 2010 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 |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.app.client; |
| |
| import com.google.gwt.animation.client.Animation; |
| import com.google.gwt.core.client.GWT; |
| import com.google.gwt.dom.client.DivElement; |
| import com.google.gwt.dom.client.SpanElement; |
| import com.google.gwt.dom.client.Style.Display; |
| import com.google.gwt.dom.client.Style.Unit; |
| import com.google.gwt.resources.client.CssResource; |
| import com.google.gwt.uibinder.client.UiBinder; |
| import com.google.gwt.uibinder.client.UiField; |
| import com.google.gwt.user.client.Timer; |
| import com.google.gwt.user.client.ui.Composite; |
| import com.google.gwt.user.client.ui.HTMLPanel; |
| |
| /** |
| * Simple widget for providing notification feedback. |
| */ |
| public class NotificationMole extends Composite { |
| /** |
| * Default CSS styles for this widget. |
| */ |
| public interface Style extends CssResource { |
| String container(); |
| |
| String notificationText(); |
| } |
| |
| interface Binder extends UiBinder<HTMLPanel, NotificationMole> { |
| } |
| |
| private class MoleAnimation extends Animation { |
| private int endSize; |
| private int startSize; |
| |
| @Override |
| protected void onComplete() { |
| if (endSize == 0) { |
| borderElement.getStyle().setDisplay(Display.NONE); |
| return; |
| } |
| borderElement.getStyle().setHeight(endSize, Unit.PX); |
| } |
| |
| @Override |
| protected void onUpdate(double progress) { |
| double delta = (endSize - startSize) * progress; |
| double newSize = startSize + delta; |
| borderElement.getStyle().setHeight(newSize, Unit.PX); |
| } |
| |
| void animateMole(int startSize, int endSize, int duration) { |
| this.startSize = startSize; |
| this.endSize = endSize; |
| if (duration == 0) { |
| onComplete(); |
| return; |
| } |
| run(duration); |
| } |
| } |
| |
| private static final Binder BINDER = GWT.create(Binder.class); |
| |
| @UiField() |
| DivElement borderElement; |
| |
| @UiField |
| DivElement heightMeasure; |
| |
| @UiField() |
| SpanElement notificationText; |
| |
| int showAttempts = 0; |
| |
| Timer showTimer = new Timer() { |
| @Override |
| public void run() { |
| if (showAttempts > 0) { |
| showImpl(); |
| } |
| } |
| }; |
| |
| private final MoleAnimation animation = new MoleAnimation(); |
| |
| private int animationDuration; |
| |
| public NotificationMole() { |
| initWidget(BINDER.createAndBindUi(this)); |
| } |
| |
| /** |
| * Hides the notification. |
| */ |
| public void hide() { |
| if (showAttempts > 0) { |
| --showAttempts; |
| } |
| if (showAttempts == 0) { |
| animation.animateMole(heightMeasure.getOffsetHeight(), 0, |
| animationDuration); |
| return; |
| } |
| } |
| |
| /** |
| * Force mole to hide and discard outstanding show attempts. |
| */ |
| public void hideNow() { |
| showAttempts = 0; |
| animation.animateMole(heightMeasure.getOffsetHeight(), 0, animationDuration); |
| } |
| |
| /** |
| * Sets the animation duration in milliseconds. The animation duration |
| * defaults to 0 if this method is never called. |
| * |
| * @param duration the animation duration in milliseconds. |
| */ |
| public void setAnimationDuration(int duration) { |
| this.animationDuration = duration; |
| } |
| |
| /** |
| * Sets the message text to be displayed. |
| * |
| * @param message the text to be displayed. |
| */ |
| public void setMessage(String message) { |
| notificationText.setInnerText(message); |
| } |
| |
| /** |
| * Display the notification with the existing message. |
| */ |
| public void show() { |
| ++showAttempts; |
| showImpl(); |
| } |
| |
| /** |
| * Set the message text and then display the notification. |
| */ |
| public void show(String message) { |
| setMessage(message); |
| show(); |
| } |
| |
| /** |
| * Display the notification, but after a delay. |
| * |
| * @param delay delay in milliseconds. |
| */ |
| public void showDelayed(int delay) { |
| if (showAttempts == 0) { |
| if (delay == 0) { |
| show(); |
| } else { |
| ++showAttempts; |
| showTimer.schedule(delay); |
| } |
| } |
| } |
| |
| private void showImpl() { |
| borderElement.getStyle().setDisplay(Display.BLOCK); |
| borderElement.getStyle().setWidth(notificationText.getOffsetWidth(), |
| Unit.PX); |
| animation.animateMole(0, heightMeasure.getOffsetHeight(), animationDuration); |
| } |
| } |