summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2013-03-25 23:37:45 +0200
committerVaadin Code Review <review@vaadin.com>2013-04-03 06:42:55 +0000
commitce2df6d10370c669a512e96f0693fc37cf02aca1 (patch)
tree5b12cf84ba967b17d96c0a5913030e23a491eeb6 /client
parent9586a30b64bfd1e8645574d9d7b6568d52dc9e25 (diff)
downloadvaadin-framework-ce2df6d10370c669a512e96f0693fc37cf02aca1.tar.gz
vaadin-framework-ce2df6d10370c669a512e96f0693fc37cf02aca1.zip
Enable setting loading indicator delays from the server (#7448)
* Refactored LoadingIndicator to a separate class on client side to enable customization and to remove clutter from ApplicationConnection Change-Id: I12e94294beed9c65a5710bdfe2486bc0f1b92bd9
Diffstat (limited to 'client')
-rw-r--r--client/src/com/vaadin/client/ApplicationConnection.java104
-rw-r--r--client/src/com/vaadin/client/VLoadingIndicator.java218
-rw-r--r--client/src/com/vaadin/client/ui/ui/UIConnector.java10
3 files changed, 249 insertions, 83 deletions
diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java
index a043ec6c0b..d59abc892a 100644
--- a/client/src/com/vaadin/client/ApplicationConnection.java
+++ b/client/src/com/vaadin/client/ApplicationConnection.java
@@ -177,11 +177,6 @@ public class ApplicationConnection {
private VContextMenu contextMenu = null;
- private Timer loadTimer;
- private Timer loadTimer2;
- private Timer loadTimer3;
- private Element loadElement;
-
private final UIConnector uIConnector;
protected boolean applicationRunning = false;
@@ -378,6 +373,8 @@ public class ApplicationConnection {
private CommunicationErrorHandler communicationErrorDelegate = null;
+ private VLoadingIndicator loadingIndicator;
+
public static class MultiStepDuration extends Duration {
private int previousStep = elapsedMillis();
@@ -404,6 +401,8 @@ public class ApplicationConnection {
layoutManager = GWT.create(LayoutManager.class);
layoutManager.setConnection(this);
tooltip = GWT.create(VTooltip.class);
+ loadingIndicator = GWT.create(VLoadingIndicator.class);
+ loadingIndicator.setConnection(this);
}
public void init(WidgetSet widgetSet, ApplicationConfiguration cnf) {
@@ -436,7 +435,7 @@ public class ApplicationConnection {
tooltip.setOwner(uIConnector.getWidget());
- showLoadingIndicator();
+ getLoadingIndicator().trigger();
scheduleHeartbeat();
@@ -987,7 +986,7 @@ public class ApplicationConnection {
*/
protected boolean isCSSLoaded() {
return cssLoaded
- || DOM.getElementPropertyInt(loadElement, "offsetHeight") != 0;
+ || getLoadingIndicator().getElement().getOffsetHeight() != 0;
}
/**
@@ -1085,25 +1084,7 @@ public class ApplicationConnection {
}
hasActiveRequest = true;
requestStartTime = new Date();
- // show initial throbber
- if (loadTimer == null) {
- loadTimer = new Timer() {
- @Override
- public void run() {
- /*
- * IE7 does not properly cancel the event with
- * loadTimer.cancel() so we have to check that we really
- * should make it visible
- */
- if (loadTimer != null) {
- showLoadingIndicator();
- }
-
- }
- };
- // First one kicks in at 300ms
- }
- loadTimer.schedule(300);
+ loadingIndicator.trigger();
eventBus.fireEvent(new RequestStartingEvent(this));
}
@@ -1129,7 +1110,7 @@ public class ApplicationConnection {
@Override
public void execute() {
if (!hasActiveRequest()) {
- hideLoadingIndicator();
+ getLoadingIndicator().hide();
// If on Liferay and session expiration management is in
// use, extend session duration on each request.
@@ -1182,54 +1163,6 @@ public class ApplicationConnection {
}
}
- private void showLoadingIndicator() {
- // show initial throbber
- if (loadElement == null) {
- loadElement = DOM.createDiv();
- DOM.setStyleAttribute(loadElement, "position", "absolute");
- DOM.appendChild(uIConnector.getWidget().getElement(), loadElement);
- VConsole.log("inserting load indicator");
- }
- DOM.setElementProperty(loadElement, "className", "v-loading-indicator");
- DOM.setStyleAttribute(loadElement, "display", "block");
- // Initialize other timers
- loadTimer2 = new Timer() {
- @Override
- public void run() {
- DOM.setElementProperty(loadElement, "className",
- "v-loading-indicator-delay");
- }
- };
- // Second one kicks in at 1500ms from request start
- loadTimer2.schedule(1200);
-
- loadTimer3 = new Timer() {
- @Override
- public void run() {
- DOM.setElementProperty(loadElement, "className",
- "v-loading-indicator-wait");
- }
- };
- // Third one kicks in at 5000ms from request start
- loadTimer3.schedule(4700);
- }
-
- private void hideLoadingIndicator() {
- if (loadTimer != null) {
- loadTimer.cancel();
- loadTimer = null;
- }
- if (loadTimer2 != null) {
- loadTimer2.cancel();
- loadTimer3.cancel();
- loadTimer2 = null;
- loadTimer3 = null;
- }
- if (loadElement != null) {
- DOM.setStyleAttribute(loadElement, "display", "none");
- }
- }
-
/**
* Checks if deferred commands are (potentially) still being executed as a
* result of an update from the server. Returns true if a deferred command
@@ -1252,19 +1185,24 @@ public class ApplicationConnection {
}
/**
+ * Returns the loading indicator used by this ApplicationConnection
+ *
+ * @return The loading indicator for this ApplicationConnection
+ */
+ public VLoadingIndicator getLoadingIndicator() {
+ return loadingIndicator;
+ }
+
+ /**
* Determines whether or not the loading indicator is showing.
*
* @return true if the loading indicator is visible
+ * @deprecated As of 7.1. Use {@link #getLoadingIndicator()} and
+ * {@link VLoadingIndicator#isVisible()}.isVisible() instead.
*/
+ @Deprecated
public boolean isLoadingIndicatorVisible() {
- if (loadElement == null) {
- return false;
- }
- if (loadElement.getStyle().getProperty("display").equals("none")) {
- return false;
- }
-
- return true;
+ return getLoadingIndicator().isVisible();
}
private static native ValueMap parseJSONResponse(String jsonText)
diff --git a/client/src/com/vaadin/client/VLoadingIndicator.java b/client/src/com/vaadin/client/VLoadingIndicator.java
new file mode 100644
index 0000000000..ca29d6a042
--- /dev/null
+++ b/client/src/com/vaadin/client/VLoadingIndicator.java
@@ -0,0 +1,218 @@
+package com.vaadin.client;
+
+import com.google.gwt.dom.client.Style.Display;
+import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Timer;
+
+/**
+ * Class representing the loading indicator for Vaadin applications. The loading
+ * indicator has four states: "triggered", "initial", "delay" and "wait". When
+ * {@link #trigger()} is called the indicator moves to its "triggered" state and
+ * then transitions from one state to the next when the timeouts specified using
+ * the set*StateDelay methods occur.
+ *
+ * @author Vaadin Ltd
+ * @since 7.1
+ */
+public class VLoadingIndicator {
+
+ private static final String PRIMARY_STYLE_NAME = "v-loading-indicator";
+
+ private ApplicationConnection connection;
+
+ private int initialStateDelay = 300;
+ private int delayStateDelay = 1500;
+ private int waitStateDelay = 5000;
+
+ private Timer initialTimer = new Timer() {
+ @Override
+ public void run() {
+ show();
+ }
+ };
+ private Timer delayStateTimer = new Timer() {
+ @Override
+ public void run() {
+ getElement().setClassName(PRIMARY_STYLE_NAME + "-delay");
+ }
+ };
+ private Timer waitStateTimer = new Timer() {
+ @Override
+ public void run() {
+ getElement().setClassName(PRIMARY_STYLE_NAME + "-wait");
+ }
+ };
+
+ private Element element;
+
+ /**
+ * Returns the delay (in ms) which must pass before the loading indicator
+ * moves into the "initial" state and is shown to the user
+ *
+ * @return The delay (in ms) until moving into the "initial" state. Counted
+ * from when {@link #trigger()} is called.
+ */
+ public int getInitialStateDelay() {
+ return initialStateDelay;
+ }
+
+ /**
+ * Sets the delay (in ms) which must pass before the loading indicator moves
+ * into the "initial" state and is shown to the user
+ *
+ * @param initialStateDelay
+ * The delay (in ms) until moving into the "initial" state.
+ * Counted from when {@link #trigger()} is called.
+ */
+ public void setInitialStateDelay(int initialStateDelay) {
+ this.initialStateDelay = initialStateDelay;
+ }
+
+ /**
+ * Returns the delay (in ms) which must pass before the loading indicator
+ * moves to its "delay" state.
+ *
+ * @return The delay (in ms) until the loading indicator moves into its
+ * "delay" state. Counted from when {@link #trigger()} is called.
+ */
+ public int getDelayStateDelay() {
+ return delayStateDelay;
+ }
+
+ /**
+ * Sets the delay (in ms) which must pass before the loading indicator moves
+ * to its "delay" state.
+ *
+ * @param delayStateDelay
+ * The delay (in ms) until the loading indicator moves into its
+ * "delay" state. Counted from when {@link #trigger()} is called.
+ */
+ public void setDelayStateDelay(int delayStateDelay) {
+ this.delayStateDelay = delayStateDelay;
+ }
+
+ /**
+ * Returns the delay (in ms) which must pass before the loading indicator
+ * moves to its "wait" state.
+ *
+ * @return The delay (in ms) until the loading indicator moves into its
+ * "wait" state. Counted from when {@link #trigger()} is called.
+ */
+ public int getWaitStateDelay() {
+ return waitStateDelay;
+ }
+
+ /**
+ * Sets the delay (in ms) which must pass before the loading indicator moves
+ * to its "wait" state.
+ *
+ * @param loadingIndicatorThirdDelay
+ * The delay (in ms) from the event until changing the loading
+ * indicator into its "wait" state. Counted from when
+ * {@link #trigger()} is called.
+ */
+ public void setWaitStateDelay(int loadingIndicatorThirdDelay) {
+ waitStateDelay = loadingIndicatorThirdDelay;
+ }
+
+ /**
+ * Triggers displaying of this loading indicator. The loading indicator will
+ * actually be shown by {@link #show()} when the initial delay (as specified
+ * by {@link #getInitialStateDelay()}) has passed.
+ * <p>
+ * The loading indicator will be hidden if shown when calling this method.
+ * </p>
+ */
+ public void trigger() {
+ hide();
+ initialTimer.schedule(getInitialStateDelay());
+ }
+
+ /**
+ * Shows the loading indicator in its standard state and triggers timers for
+ * transitioning into the "delay" and "wait" states.
+ */
+ public void show() {
+ // Reset possible style name and display mode
+ getElement().setClassName(PRIMARY_STYLE_NAME);
+ getElement().getStyle().setDisplay(Display.BLOCK);
+
+ // Schedule the "delay" loading indicator
+ int delayStateTimerDelay = getDelayStateDelay()
+ - getInitialStateDelay();
+ if (delayStateTimerDelay >= 0) {
+ delayStateTimer.schedule(delayStateTimerDelay);
+ }
+
+ // Schedule the "wait" loading indicator
+ int waitStateTimerDelay = getWaitStateDelay() - getInitialStateDelay();
+ if (waitStateTimerDelay >= 0) {
+ waitStateTimer.schedule(waitStateTimerDelay);
+ }
+ }
+
+ /**
+ * Returns the {@link ApplicationConnection} which uses this loading
+ * indicator
+ *
+ * @return The ApplicationConnection for this loading indicator
+ */
+ public ApplicationConnection getConnection() {
+ return connection;
+ }
+
+ /**
+ * Sets the {@link ApplicationConnection} which uses this loading indicator.
+ * Only used internally.
+ *
+ * @param connection
+ * The ApplicationConnection for this loading indicator
+ */
+ void setConnection(ApplicationConnection connection) {
+ this.connection = connection;
+ }
+
+ /**
+ * Hides the loading indicator (if visible). Cancels any possibly running
+ * timers.
+ */
+ public void hide() {
+ initialTimer.cancel();
+ delayStateTimer.cancel();
+ waitStateTimer.cancel();
+
+ getElement().getStyle().setDisplay(Display.NONE);
+ }
+
+ /**
+ * Returns whether or not the loading indicator is showing.
+ *
+ * @return true if the loading indicator is visible, false otherwise
+ */
+ public boolean isVisible() {
+ if (getElement().getStyle().getDisplay()
+ .equals(Display.NONE.getCssName())) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the root element of the loading indicator
+ *
+ * @return The loading indicator DOM element
+ */
+ public Element getElement() {
+ if (element == null) {
+ element = DOM.createDiv();
+ element.getStyle().setPosition(Position.ABSOLUTE);
+ getConnection().getUIConnector().getWidget().getElement()
+ .appendChild(element);
+ }
+ return element;
+ }
+
+}
diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java
index b8b7786d21..f4524882fa 100644
--- a/client/src/com/vaadin/client/ui/ui/UIConnector.java
+++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java
@@ -615,5 +615,15 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
getConnection().getVTooltip().setMaxWidth(
getState().tooltipConfiguration.maxWidth);
}
+
+ if (stateChangeEvent
+ .hasPropertyChanged("loadingIndicatorConfiguration")) {
+ getConnection().getLoadingIndicator().setInitialStateDelay(
+ getState().loadingIndicatorConfiguration.initialDelay);
+ getConnection().getLoadingIndicator().setWaitStateDelay(
+ getState().loadingIndicatorConfiguration.waitStateDelay);
+ getConnection().getLoadingIndicator().setDelayStateDelay(
+ getState().loadingIndicatorConfiguration.delayStateDelay);
+ }
}
}