/* * SlideLabel.java * * Copyright (C) 2009-12 by RStudio, Inc. * * Unless you have received this program directly from RStudio pursuant * to the terms of a commercial license agreement with RStudio, then * this program is licensed to you under the terms of version 3 of the * GNU Affero General Public License. This program is distributed WITHOUT * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. * */ package org.rstudio.core.client.widget; import com.google.gwt.animation.client.Animation; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.*; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.CssResource; import com.google.gwt.resources.client.DataResource; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.LayoutPanel; import com.google.gwt.user.client.ui.Widget; import org.rstudio.core.client.resources.CoreResources; public class SlideLabel extends Composite { private static SlideLabelUiBinder uiBinder = GWT .create(SlideLabelUiBinder.class); static Resources RESOURCES = (Resources)GWT.create(Resources.class); public static void ensureStylesInjected() { RESOURCES.style().ensureInjected(); } interface SlideLabelUiBinder extends UiBinder<Widget, SlideLabel> { } interface Resources extends ClientBundle { @Source("SlideLabel.css") SlideLabelCss style(); @Source("slideLabelBottom.png") DataResource slideLabelBottom(); @Source("slideLabelBottomLeft.png") DataResource slideLabelBottomLeft(); @Source("slideLabelBottomRight.png") DataResource slideLabelBottomRight(); @Source("slideLabelFill.png") DataResource slideLabelFill(); @Source("slideLabelLeft.png") DataResource slideLabelLeft(); @Source("slideLabelRight.png") DataResource slideLabelRight(); } interface SlideLabelCss extends CssResource { String curtain(); String border(); String progress(); String content(); String W(); String C(); String E(); String SW(); String S(); String SE(); String cancelColumn(); String cancelButton(); } public static Command show(String label, boolean asHtml, boolean showProgressSpinner, final LayoutPanel panel) { final SlideLabel slideLabel = showInternal(label, asHtml, showProgressSpinner, panel); slideLabel.show(); return new Command() { public void execute() { panel.remove(slideLabel); } }; } public static void show(String label, boolean asHtml, boolean showProgressSpinner, int autoHideMillis, final LayoutPanel panel) { final SlideLabel slideLabel = showInternal(label, asHtml, showProgressSpinner, panel); slideLabel.show(autoHideMillis, new Command() { public void execute() { panel.remove(slideLabel); } }); } private static SlideLabel showInternal(String label, boolean asHtml, boolean showProgressSpinner, LayoutPanel panel) { final SlideLabel slideLabel = new SlideLabel(showProgressSpinner); slideLabel.setText(label, asHtml); panel.add(slideLabel); panel.setWidgetLeftRight(slideLabel, 0, Style.Unit.PX, 0, Style.Unit.PX); panel.setWidgetTopHeight(slideLabel, 0, Style.Unit.PX, 100, Style.Unit.PX); panel.forceLayout(); return slideLabel; } public SlideLabel(boolean showProgressSpinner) { initWidget(uiBinder.createAndBindUi(this)); if (showProgressSpinner) progress_.setSrc(CoreResources.INSTANCE.progress_gray_as_data().getSafeUri().asString()); else progress_.getStyle().setDisplay(Style.Display.NONE); curtain_.setHeight("0px"); cancel_.setVisible(false); cancel_.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent arg0) { if (onCancel_ != null) { onCancel_.execute(); } } }); } public void setText(String label, boolean asHtml) { if (asHtml) content_.setInnerHTML(label); else content_.setInnerText(label); } public void show() { show(-1, null); } public void show(final int autoHideMillis, final Command executeOnComplete) { assert autoHideMillis >= 0 || executeOnComplete == null: "Possible error: executeOnComplete will never be called with " + "negative value for autoHideMillis"; Scheduler.get().scheduleDeferred(new ScheduledCommand() { public void execute() { stopCurrentAnimation(); currentAnimation_ = new Animation() { @Override protected void onStart() { setVisible(true); curtain_.setHeight("0px"); height = content_.getOffsetHeight() + 14 + 14; super.onStart(); } @Override protected void onUpdate(double progress) { setHeight(height * progress); } @Override protected void onComplete() { currentAnimation_ = null; if (autoHideMillis >= 0) { currentAutoHideTimer_ = new Timer() { @Override public void run() { currentAutoHideTimer_ = null; hide(executeOnComplete); } }; currentAutoHideTimer_.schedule(autoHideMillis); } } private int height; }; currentAnimation_.run(ANIM_MILLIS); } }); } public void hide() { hide(null); } public void hide(final Command executeOnComplete) { stopCurrentAnimation(); final int height = curtain_.getOffsetHeight(); currentAnimation_ = new Animation() { @Override protected void onUpdate(double progress) { setHeight(height * (1-progress)); } @Override protected void onComplete() { currentAnimation_ = null; super.onComplete(); setVisible(false); if (executeOnComplete != null) executeOnComplete.execute(); } }; currentAnimation_.run(ANIM_MILLIS); } public void onCancel(final Operation onCancel) { onCancel_ = onCancel; cancel_.setVisible(onCancel != null); } private void setHeight(double height) { curtain_.setHeight((int)height + "px"); } private void stopCurrentAnimation() { if (currentAnimation_ != null) { currentAnimation_.cancel(); currentAnimation_ = null; } if (currentAutoHideTimer_ != null) { currentAutoHideTimer_.cancel(); currentAutoHideTimer_ = null; } } @UiField HTMLPanel curtain_; @UiField DivElement content_; @UiField TableElement border_; @UiField ImageElement progress_; @UiField SmallButton cancel_; private Animation currentAnimation_; private Timer currentAutoHideTimer_; private Operation onCancel_; private static final int ANIM_MILLIS = 250; }