summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJouni Koivuviita <jouni.koivuviita@itmill.com>2007-11-19 10:00:18 +0000
committerJouni Koivuviita <jouni.koivuviita@itmill.com>2007-11-19 10:00:18 +0000
commit19b539cbe5a8b8f4d362781021e6bf702d15fcec (patch)
treeebe36509c114180ab2a94ddd25b4662a5c2ef284 /src
parentcce942ace82454cc3b2b546cbe88ec5cfb7e61c1 (diff)
downloadvaadin-framework-19b539cbe5a8b8f4d362781021e6bf702d15fcec.tar.gz
vaadin-framework-19b539cbe5a8b8f4d362781021e6bf702d15fcec.zip
-Implemented simple loading indicator into ApplicationConnection somewhat as suggested in #1101. Needs more work.
-Transparent PNG fix for IE6 in table.css. svn changeset:2862/svn branch:trunk
Diffstat (limited to 'src')
-rwxr-xr-xsrc/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java1032
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/public/default/common/common.css17
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/public/default/common/img/ajax-loader-big.gifbin0 -> 3208 bytes
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/public/default/common/img/ajax-loader-medium.gifbin0 -> 1849 bytes
-rwxr-xr-xsrc/com/itmill/toolkit/terminal/gwt/public/default/common/img/ajax-loader.gifbin2277 -> 4099 bytes
-rwxr-xr-xsrc/com/itmill/toolkit/terminal/gwt/public/default/common/img/loading-indicator-delay.gifbin0 -> 1590 bytes
-rwxr-xr-xsrc/com/itmill/toolkit/terminal/gwt/public/default/common/img/loading-indicator-wait.gifbin0 -> 1590 bytes
-rwxr-xr-xsrc/com/itmill/toolkit/terminal/gwt/public/default/common/img/loading-indicator.gifbin0 -> 1590 bytes
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/public/default/table/table.css3
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/public/default/tabsheet/tabsheet.css8
10 files changed, 575 insertions, 485 deletions
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java b/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java
index 7f5dc47d25..cce50f4888 100755
--- a/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java
@@ -15,6 +15,9 @@ import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.HasFocus;
import com.google.gwt.user.client.ui.HasWidgets;
@@ -27,487 +30,550 @@ import com.itmill.toolkit.terminal.gwt.client.ui.IView;
*/
public class ApplicationConnection {
- private String appUri;
-
- private HashMap resourcesMap = new HashMap();
-
- private static Console console;
-
- private Vector pendingVariables = new Vector();
-
- private HashMap idToPaintable = new HashMap();
-
- private HashMap paintableToId = new HashMap();
-
- private final WidgetSet widgetSet;
-
- private ContextMenu contextMenu = null;
-
- private IView view;
-
- public ApplicationConnection(WidgetSet widgetSet) {
- this.widgetSet = widgetSet;
- appUri = getAppUri();
-
- if (isDebugMode()) {
- console = new DebugConsole(this);
- } else {
- console = new NullConsole();
- }
-
- makeUidlRequest("repaintAll=1");
-
- // TODO remove hardcoded id name
- view = new IView("itmill-ajax-window");
-
- }
-
- public static Console getConsole() {
- return console;
- }
-
- private native static boolean isDebugMode()
- /*-{
- var uri = $wnd.location;
- var re = /debug[^\/]*$/;
- return re.test(uri);
- }-*/;
-
- public native String getAppUri()
- /*-{
- var u = $wnd.itmill.appUri;
- if (u.indexOf("/") != 0 && u.indexOf("http") != 0) {
- var b = $wnd.location.href;
- var i = b.length-1;
- while (b.charAt(i) != "/" && i>0) i--;
- b = b.substring(0,i+1);
- u = b + u;
- }
- return u;
- }-*/;
-
- private native String getPathInfo()
- /*-{
- return $wnd.itmill.pathInfo;
- }-*/;
-
- private native String getThemeUri()
- /*-{
- return $wnd.itmill.themeUri;
- }-*/;
-
- private void makeUidlRequest(String requestData) {
- console.log("Making UIDL Request with params: " + requestData);
- String uri = appUri + "/UIDL" + getPathInfo();
- RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, uri);
- rb.setHeader("Content-Type",
- "application/x-www-form-urlencoded; charset=utf-8");
- try {
- rb.sendRequest(requestData, new RequestCallback() {
- public void onError(Request request, Throwable exception) {
- // TODO Better reporting to user
- console.error("Got error");
- }
-
- public void onResponseReceived(Request request,
- Response response) {
- handleReceivedJSONMessage(response);
- }
-
- });
-
- } catch (RequestException e) {
- // TODO Better reporting to user
- console.error(e.getMessage());
- }
- }
-
- private void handleReceivedJSONMessage(Response response) {
- Date start = new Date();
- String jsonText = response.getText().substring(3) + "}";
- JSONValue json;
- try {
- json = JSONParser.parse(jsonText);
- } catch (com.google.gwt.json.client.JSONException e) {
- console.log(e.getMessage() + " - Original JSON-text:");
- console.log(jsonText);
- return;
- }
- // Handle redirect
- JSONObject redirect = (JSONObject) ((JSONObject) json).get("redirect");
- if (redirect != null) {
- JSONString url = (JSONString) redirect.get("url");
- if (url != null) {
- console.log("redirecting to " + url.stringValue());
- redirect(url.stringValue());
- return;
- }
- }
-
- // Store resources
- JSONObject resources = (JSONObject) ((JSONObject) json)
- .get("resources");
- for (Iterator i = resources.keySet().iterator(); i.hasNext();) {
- String key = (String) i.next();
- resourcesMap.put(key, ((JSONString) resources.get(key))
- .stringValue());
- }
-
- // Store locale data
- if (((JSONObject) json).containsKey("locales")) {
- JSONArray l = (JSONArray) ((JSONObject) json).get("locales");
- for (int i = 0; i < l.size(); i++) {
- LocaleService.addLocale((JSONObject) l.get(i));
- }
- }
-
- // Process changes
- JSONArray changes = (JSONArray) ((JSONObject) json).get("changes");
- for (int i = 0; i < changes.size(); i++) {
- try {
- UIDL change = new UIDL((JSONArray) changes.get(i));
- try {
- console.dirUIDL(change);
- } catch (Exception e) {
- console.log(e.getMessage());
- // TODO: dir doesn't work in any browser although it should
- // work (works in hosted mode)
- // it partially did at some part but now broken.
- }
- UIDL uidl = change.getChildUIDL(0);
- Paintable paintable = getPaintable(uidl.getId());
- if (paintable != null) {
- paintable.updateFromUIDL(uidl, this);
- } else {
- if (!uidl.getTag().equals("window")) {
- System.out.println("Received update for "
- + uidl.getTag()
- + ", but there is no such paintable ("
- + uidl.getId() + ") rendered.");
- } else {
- view.updateFromUIDL(uidl, this);
- }
- }
- } catch (Throwable e) {
- e.printStackTrace();
- }
- }
-
- if (((JSONObject) json).containsKey("meta")) {
- JSONObject meta = ((JSONObject) json).get("meta").isObject();
- if (meta.containsKey("focus")) {
- String focusPid = meta.get("focus").isString().stringValue();
- Paintable toBeFocused = getPaintable(focusPid);
- if (toBeFocused instanceof HasFocus) {
- HasFocus toBeFocusedWidget = (HasFocus) toBeFocused;
- toBeFocusedWidget.setFocus(true);
- }
- }
- }
-
- long prosessingTime = (new Date().getTime()) - start.getTime();
- console.log(" Processing time was " + String.valueOf(prosessingTime)
- + "ms for " + jsonText.length() + " characters of JSON");
- console.log("Referenced paintables: " + idToPaintable.size());
-
- }
-
- // Redirect browser
- private static native void redirect(String url)
- /*-{
- $wnd.location = url;
- }-*/;
-
- public void registerPaintable(String id, Paintable paintable) {
- idToPaintable.put(id, paintable);
- paintableToId.put(paintable, id);
- }
-
- public void unregisterPaintable(Paintable p) {
- idToPaintable.remove(paintableToId.get(p));
- paintableToId.remove(p);
-
- if (p instanceof HasWidgets) {
- unregisterChildPaintables((HasWidgets) p);
- }
- }
-
- public void unregisterChildPaintables(HasWidgets container) {
- Iterator it = container.iterator();
- while (it.hasNext()) {
- Widget w = (Widget) it.next();
- if (w instanceof Paintable) {
- unregisterPaintable((Paintable) w);
- }
- if (w instanceof HasWidgets) {
- unregisterChildPaintables((HasWidgets) w);
- }
- }
- }
-
- /**
- * Returns Paintable element by its id
- *
- * @param id
- * Paintable ID
- */
- public Paintable getPaintable(String id) {
- return (Paintable) idToPaintable.get(id);
- }
-
- private void addVariableToQueue(String paintableId, String variableName,
- String encodedValue, boolean immediate, char type) {
- String id = paintableId + "_" + variableName + "_" + type;
- for (int i = 0; i < pendingVariables.size(); i += 2) {
- if ((pendingVariables.get(i)).equals(id)) {
- pendingVariables.remove(i);
- pendingVariables.remove(i);
- break;
- }
- }
- pendingVariables.add(id);
- pendingVariables.add(encodedValue);
- if (immediate) {
- sendPendingVariableChanges();
- }
- }
-
- public void sendPendingVariableChanges() {
- StringBuffer req = new StringBuffer();
-
- req.append("changes=");
- for (int i = 0; i < pendingVariables.size(); i++) {
- if (i > 0) {
- req.append("\u0001");
- }
- req.append(pendingVariables.get(i));
- }
-
- pendingVariables.clear();
- makeUidlRequest(req.toString());
- }
-
- private static native String escapeString(String value)
- /*-{
- return encodeURIComponent(value);
- }-*/;
-
- public void updateVariable(String paintableId, String variableName,
- String newValue, boolean immediate) {
- addVariableToQueue(paintableId, variableName, escapeString(newValue),
- immediate, 's');
- }
-
- public void updateVariable(String paintableId, String variableName,
- int newValue, boolean immediate) {
- addVariableToQueue(paintableId, variableName, "" + newValue, immediate,
- 'i');
- }
-
- public void updateVariable(String paintableId, String variableName,
- long newValue, boolean immediate) {
- addVariableToQueue(paintableId, variableName, "" + newValue, immediate,
- 'l');
- }
-
- public void updateVariable(String paintableId, String variableName,
- float newValue, boolean immediate) {
- addVariableToQueue(paintableId, variableName, "" + newValue, immediate,
- 'f');
- }
-
- public void updateVariable(String paintableId, String variableName,
- double newValue, boolean immediate) {
- addVariableToQueue(paintableId, variableName, "" + newValue, immediate,
- 'd');
- }
-
- public void updateVariable(String paintableId, String variableName,
- boolean newValue, boolean immediate) {
- addVariableToQueue(paintableId, variableName, newValue ? "true"
- : "false", immediate, 'b');
- }
-
- public void updateVariable(String paintableId, String variableName,
- Object[] values, boolean immediate) {
- StringBuffer buf = new StringBuffer();
- for (int i = 0; i < values.length; i++) {
- if (i > 0) {
- buf.append(",");
- }
- buf.append(escapeString(values[i].toString()));
- }
- addVariableToQueue(paintableId, variableName, buf.toString(),
- immediate, 'a');
- }
-
- public static Container getParentLayout(Widget component) {
- Widget parent = component.getParent();
- while (parent != null && !(parent instanceof Container)) {
- parent = parent.getParent();
- }
- if (parent != null && ((Container) parent).hasChildComponent(component)) {
- return (Container) parent;
- }
- return null;
- }
-
- /**
- * Update generic component features.
- *
- * <h2>Selecting correct implementation</h2>
- *
- * <p>
- * The implementation of a component depends on many properties, including
- * styles, component features, etc. Sometimes the user changes those
- * properties after the component has been created. Calling this method in
- * the beginning of your updateFromUIDL -method automatically replaces your
- * component with more appropriate if the requested implementation changes.
- * </p>
- *
- * <h2>Caption, icon, error messages and description</h2>
- *
- * <p>
- * Component can delegate management of caption, icon, error messages and
- * description to parent layout. This is optional an should be decided by
- * component author
- * </p>
- *
- * <h2>Component visibility and disabling</h2>
- *
- * This method will manage component visibility automatically and if
- * component is an instanceof FocusWidget, also handle component disabling
- * when needed.
- *
- * @param currentWidget
- * Current widget that might need replacement
- * @param uidl
- * UIDL to be painted
- * @param manageCaption
- * True if you want to delegate caption, icon, description
- * and error message management to parent.
- *
- * @return Returns true iff no further painting is needed by caller
- */
- public boolean updateComponent(Widget component, UIDL uidl,
- boolean manageCaption) {
-
- // If the server request that a cached instance should be used, do
- // nothing
- if (uidl.getBooleanAttribute("cached")) {
- return true;
- }
-
- // Visibility
- boolean visible = !uidl.getBooleanAttribute("invisible");
- component.setVisible(visible);
- if (!visible) {
- return true;
- }
-
- // Switch to correct implementation if needed
- if (!widgetSet.isCorrectImplementation(component, uidl)) {
- Container parent = getParentLayout(component);
- if (parent != null) {
- Widget w = widgetSet.createWidget(uidl);
- parent.replaceChildComponent(component, w);
- registerPaintable(uidl.getId(), (Paintable) w);
- ((Paintable) w).updateFromUIDL(uidl, this);
- return true;
- }
- }
-
- // Set captions
- // TODO Manage Error messages
- if (manageCaption) {
- Container parent = getParentLayout(component);
- if (parent != null) {
- parent.updateCaption((Paintable) component, uidl);
- }
- }
-
- // Styles + disabled & readonly
- component.setStyleName(component.getStylePrimaryName());
-
- // first disabling and read-only status
- boolean enabled = true;
- if (uidl.hasAttribute("disabled")) {
- enabled = !uidl.getBooleanAttribute("disabled");
- } else if (uidl.hasAttribute("readonly")) {
- enabled = !uidl.getBooleanAttribute("readonly");
- }
- if (component instanceof FocusWidget) {
- ((FocusWidget) component).setEnabled(enabled);
- }
- if (!enabled) {
- component.addStyleName("i-disabled");
- } else {
- component.removeStyleName("i-disabled");
- }
-
- // add additional styles as css classes, prefixed with component default
- // stylename
- if (uidl.hasAttribute("style")) {
- String[] styles = uidl.getStringAttribute("style").split(" ");
- for (int i = 0; i < styles.length; i++) {
- component.addStyleDependentName(styles[i]);
- }
- }
-
- return false;
- }
-
- /**
- * Get either existing or new widget for given UIDL.
- *
- * If corresponding paintable has been previously painted, return it.
- * Otherwise create and register a new widget from UIDL. Caller must update
- * the returned widget from UIDL after it has been connected to parent.
- *
- * @param uidl
- * UIDL to create widget from.
- * @return Either existing or new widget corresponding to UIDL.
- */
- public Widget getWidget(UIDL uidl) {
- String id = uidl.getId();
- Widget w = (Widget) getPaintable(id);
- if (w != null) {
- return w;
- }
- w = widgetSet.createWidget(uidl);
- registerPaintable(id, (Paintable) w);
- return w;
- }
-
- public String getResource(String name) {
- return (String) resourcesMap.get(name);
- }
-
- /**
- * Singleton method to get instance of app's context menu.
- *
- * @return IContextMenu object
- */
- public ContextMenu getContextMenu() {
- if (contextMenu == null) {
- contextMenu = new ContextMenu();
- }
- return contextMenu;
- }
-
- /**
- * Translates custom protocols in UIRL URI's to be recognizable by browser.
- * All uri's from UIDL should be routed via this method before giving them
- * to browser due URI's in UIDL may contain custom protocols like theme://.
- *
- * @param toolkitUri
- * toolkit URI from uidl
- * @return translated URI ready for browser
- */
- public String translateToolkitUri(String toolkitUri) {
- if (toolkitUri.startsWith("theme")) {
- toolkitUri = getThemeUri() + toolkitUri.substring(7);
- }
- return toolkitUri;
- }
+ private String appUri;
+
+ private HashMap resourcesMap = new HashMap();
+
+ private static Console console;
+
+ private Vector pendingVariables = new Vector();
+
+ private HashMap idToPaintable = new HashMap();
+
+ private HashMap paintableToId = new HashMap();
+
+ private final WidgetSet widgetSet;
+
+ private ContextMenu contextMenu = null;
+
+ private Timer loadTimer;
+ private Element loadElement;
+
+ private IView view;
+
+ public ApplicationConnection(WidgetSet widgetSet) {
+ this.widgetSet = widgetSet;
+ appUri = getAppUri();
+
+ if (isDebugMode()) {
+ console = new DebugConsole(this);
+ } else {
+ console = new NullConsole();
+ }
+
+ makeUidlRequest("repaintAll=1");
+
+ // TODO remove hardcoded id name
+ view = new IView("itmill-ajax-window");
+
+ }
+
+ public static Console getConsole() {
+ return console;
+ }
+
+ private native static boolean isDebugMode()
+ /*-{
+ var uri = $wnd.location;
+ var re = /debug[^\/]*$/;
+ return re.test(uri);
+ }-*/;
+
+ public native String getAppUri()
+ /*-{
+ var u = $wnd.itmill.appUri;
+ if (u.indexOf("/") != 0 && u.indexOf("http") != 0) {
+ var b = $wnd.location.href;
+ var i = b.length-1;
+ while (b.charAt(i) != "/" && i>0) i--;
+ b = b.substring(0,i+1);
+ u = b + u;
+ }
+ return u;
+ }-*/;
+
+ private native String getPathInfo()
+ /*-{
+ return $wnd.itmill.pathInfo;
+ }-*/;
+
+ private native String getThemeUri()
+ /*-{
+ return $wnd.itmill.themeUri;
+ }-*/;
+
+ private void makeUidlRequest(String requestData) {
+
+ // place loading indicator
+ showLoadingIndicator();
+
+ console.log("Making UIDL Request with params: " + requestData);
+ String uri = appUri + "/UIDL" + getPathInfo();
+ RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, uri);
+ rb.setHeader("Content-Type",
+ "application/x-www-form-urlencoded; charset=utf-8");
+ try {
+ rb.sendRequest(requestData, new RequestCallback() {
+ public void onError(Request request, Throwable exception) {
+ // TODO Better reporting to user
+ console.error("Got error");
+ }
+
+ public void onResponseReceived(Request request,
+ Response response) {
+ handleReceivedJSONMessage(response);
+ }
+
+ });
+
+ } catch (RequestException e) {
+ // TODO Better reporting to user
+ console.error(e.getMessage());
+ }
+ }
+
+ private void showLoadingIndicator() {
+ loadTimer = new Timer() {
+ public void run() {
+ // show initial throbber
+ if (loadElement == null) {
+ loadElement = DOM.createDiv();
+ DOM.setStyleAttribute(loadElement, "position", "absolute");
+ DOM.appendChild(view.getElement(), loadElement);
+ }
+ DOM.setElementProperty(loadElement, "className",
+ "i-loading-indicator");
+ DOM.setStyleAttribute(loadElement, "display", "block");
+ // Position
+ DOM.setStyleAttribute(loadElement, "top", (view
+ .getAbsoluteTop() + 6)
+ + "px");
+ DOM.setStyleAttribute(loadElement, "left",
+ (view.getAbsoluteLeft()
+ + view.getOffsetWidth()
+ - DOM.getElementPropertyInt(loadElement,
+ "offsetWidth") - 5)
+ + "px");
+
+ // Initialize other timers
+ Timer delay = new Timer() {
+ public void run() {
+ DOM.setElementProperty(loadElement, "className",
+ "i-loading-indicator-delay");
+ }
+ };
+ // Second one kicks in at 1500ms
+ delay.schedule(1200);
+
+ Timer wait = new Timer() {
+ public void run() {
+ DOM.setElementProperty(loadElement, "className",
+ "i-loading-indicator-wait");
+ }
+ };
+ // Third one kicks in at 5000ms
+ wait.schedule(4700);
+ }
+ };
+ // First one kicks in at 300ms
+ loadTimer.schedule(300);
+ }
+
+ private void hideLoadingIndicator() {
+ if (loadTimer != null)
+ loadTimer.cancel();
+ if (loadElement != null)
+ DOM.setStyleAttribute(loadElement, "display", "none");
+ }
+
+ private void handleReceivedJSONMessage(Response response) {
+ hideLoadingIndicator();
+
+ Date start = new Date();
+ String jsonText = response.getText().substring(3) + "}";
+ JSONValue json;
+ try {
+ json = JSONParser.parse(jsonText);
+ } catch (com.google.gwt.json.client.JSONException e) {
+ console.log(e.getMessage() + " - Original JSON-text:");
+ console.log(jsonText);
+ return;
+ }
+ // Handle redirect
+ JSONObject redirect = (JSONObject) ((JSONObject) json).get("redirect");
+ if (redirect != null) {
+ JSONString url = (JSONString) redirect.get("url");
+ if (url != null) {
+ console.log("redirecting to " + url.stringValue());
+ redirect(url.stringValue());
+ return;
+ }
+ }
+
+ // Store resources
+ JSONObject resources = (JSONObject) ((JSONObject) json)
+ .get("resources");
+ for (Iterator i = resources.keySet().iterator(); i.hasNext();) {
+ String key = (String) i.next();
+ resourcesMap.put(key, ((JSONString) resources.get(key))
+ .stringValue());
+ }
+
+ // Store locale data
+ if (((JSONObject) json).containsKey("locales")) {
+ JSONArray l = (JSONArray) ((JSONObject) json).get("locales");
+ for (int i = 0; i < l.size(); i++) {
+ LocaleService.addLocale((JSONObject) l.get(i));
+ }
+ }
+
+ // Process changes
+ JSONArray changes = (JSONArray) ((JSONObject) json).get("changes");
+ for (int i = 0; i < changes.size(); i++) {
+ try {
+ UIDL change = new UIDL((JSONArray) changes.get(i));
+ try {
+ console.dirUIDL(change);
+ } catch (Exception e) {
+ console.log(e.getMessage());
+ // TODO: dir doesn't work in any browser although it should
+ // work (works in hosted mode)
+ // it partially did at some part but now broken.
+ }
+ UIDL uidl = change.getChildUIDL(0);
+ Paintable paintable = getPaintable(uidl.getId());
+ if (paintable != null) {
+ paintable.updateFromUIDL(uidl, this);
+ } else {
+ if (!uidl.getTag().equals("window")) {
+ System.out.println("Received update for "
+ + uidl.getTag()
+ + ", but there is no such paintable ("
+ + uidl.getId() + ") rendered.");
+ } else {
+ view.updateFromUIDL(uidl, this);
+ }
+ }
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (((JSONObject) json).containsKey("meta")) {
+ JSONObject meta = ((JSONObject) json).get("meta").isObject();
+ if (meta.containsKey("focus")) {
+ String focusPid = meta.get("focus").isString().stringValue();
+ Paintable toBeFocused = getPaintable(focusPid);
+ if (toBeFocused instanceof HasFocus) {
+ HasFocus toBeFocusedWidget = (HasFocus) toBeFocused;
+ toBeFocusedWidget.setFocus(true);
+ }
+ }
+ }
+
+ long prosessingTime = (new Date().getTime()) - start.getTime();
+ console.log(" Processing time was " + String.valueOf(prosessingTime)
+ + "ms for " + jsonText.length() + " characters of JSON");
+ console.log("Referenced paintables: " + idToPaintable.size());
+
+ }
+
+ // Redirect browser
+ private static native void redirect(String url)
+ /*-{
+ $wnd.location = url;
+ }-*/;
+
+ public void registerPaintable(String id, Paintable paintable) {
+ idToPaintable.put(id, paintable);
+ paintableToId.put(paintable, id);
+ }
+
+ public void unregisterPaintable(Paintable p) {
+ idToPaintable.remove(paintableToId.get(p));
+ paintableToId.remove(p);
+
+ if (p instanceof HasWidgets) {
+ unregisterChildPaintables((HasWidgets) p);
+ }
+ }
+
+ public void unregisterChildPaintables(HasWidgets container) {
+ Iterator it = container.iterator();
+ while (it.hasNext()) {
+ Widget w = (Widget) it.next();
+ if (w instanceof Paintable) {
+ unregisterPaintable((Paintable) w);
+ }
+ if (w instanceof HasWidgets) {
+ unregisterChildPaintables((HasWidgets) w);
+ }
+ }
+ }
+
+ /**
+ * Returns Paintable element by its id
+ *
+ * @param id
+ * Paintable ID
+ */
+ public Paintable getPaintable(String id) {
+ return (Paintable) idToPaintable.get(id);
+ }
+
+ private void addVariableToQueue(String paintableId, String variableName,
+ String encodedValue, boolean immediate, char type) {
+ String id = paintableId + "_" + variableName + "_" + type;
+ for (int i = 0; i < pendingVariables.size(); i += 2) {
+ if ((pendingVariables.get(i)).equals(id)) {
+ pendingVariables.remove(i);
+ pendingVariables.remove(i);
+ break;
+ }
+ }
+ pendingVariables.add(id);
+ pendingVariables.add(encodedValue);
+ if (immediate) {
+ sendPendingVariableChanges();
+ }
+ }
+
+ public void sendPendingVariableChanges() {
+ StringBuffer req = new StringBuffer();
+
+ req.append("changes=");
+ for (int i = 0; i < pendingVariables.size(); i++) {
+ if (i > 0) {
+ req.append("\u0001");
+ }
+ req.append(pendingVariables.get(i));
+ }
+
+ pendingVariables.clear();
+ makeUidlRequest(req.toString());
+ }
+
+ private static native String escapeString(String value)
+ /*-{
+ return encodeURIComponent(value);
+ }-*/;
+
+ public void updateVariable(String paintableId, String variableName,
+ String newValue, boolean immediate) {
+ addVariableToQueue(paintableId, variableName, escapeString(newValue),
+ immediate, 's');
+ }
+
+ public void updateVariable(String paintableId, String variableName,
+ int newValue, boolean immediate) {
+ addVariableToQueue(paintableId, variableName, "" + newValue, immediate,
+ 'i');
+ }
+
+ public void updateVariable(String paintableId, String variableName,
+ long newValue, boolean immediate) {
+ addVariableToQueue(paintableId, variableName, "" + newValue, immediate,
+ 'l');
+ }
+
+ public void updateVariable(String paintableId, String variableName,
+ float newValue, boolean immediate) {
+ addVariableToQueue(paintableId, variableName, "" + newValue, immediate,
+ 'f');
+ }
+
+ public void updateVariable(String paintableId, String variableName,
+ double newValue, boolean immediate) {
+ addVariableToQueue(paintableId, variableName, "" + newValue, immediate,
+ 'd');
+ }
+
+ public void updateVariable(String paintableId, String variableName,
+ boolean newValue, boolean immediate) {
+ addVariableToQueue(paintableId, variableName, newValue ? "true"
+ : "false", immediate, 'b');
+ }
+
+ public void updateVariable(String paintableId, String variableName,
+ Object[] values, boolean immediate) {
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < values.length; i++) {
+ if (i > 0) {
+ buf.append(",");
+ }
+ buf.append(escapeString(values[i].toString()));
+ }
+ addVariableToQueue(paintableId, variableName, buf.toString(),
+ immediate, 'a');
+ }
+
+ public static Container getParentLayout(Widget component) {
+ Widget parent = component.getParent();
+ while (parent != null && !(parent instanceof Container)) {
+ parent = parent.getParent();
+ }
+ if (parent != null && ((Container) parent).hasChildComponent(component)) {
+ return (Container) parent;
+ }
+ return null;
+ }
+
+ /**
+ * Update generic component features.
+ *
+ * <h2>Selecting correct implementation</h2>
+ *
+ * <p>
+ * The implementation of a component depends on many properties, including
+ * styles, component features, etc. Sometimes the user changes those
+ * properties after the component has been created. Calling this method in
+ * the beginning of your updateFromUIDL -method automatically replaces your
+ * component with more appropriate if the requested implementation changes.
+ * </p>
+ *
+ * <h2>Caption, icon, error messages and description</h2>
+ *
+ * <p>
+ * Component can delegate management of caption, icon, error messages and
+ * description to parent layout. This is optional an should be decided by
+ * component author
+ * </p>
+ *
+ * <h2>Component visibility and disabling</h2>
+ *
+ * This method will manage component visibility automatically and if
+ * component is an instanceof FocusWidget, also handle component disabling
+ * when needed.
+ *
+ * @param currentWidget
+ * Current widget that might need replacement
+ * @param uidl
+ * UIDL to be painted
+ * @param manageCaption
+ * True if you want to delegate caption, icon, description and
+ * error message management to parent.
+ *
+ * @return Returns true iff no further painting is needed by caller
+ */
+ public boolean updateComponent(Widget component, UIDL uidl,
+ boolean manageCaption) {
+
+ // If the server request that a cached instance should be used, do
+ // nothing
+ if (uidl.getBooleanAttribute("cached")) {
+ return true;
+ }
+
+ // Visibility
+ boolean visible = !uidl.getBooleanAttribute("invisible");
+ component.setVisible(visible);
+ if (!visible) {
+ return true;
+ }
+
+ // Switch to correct implementation if needed
+ if (!widgetSet.isCorrectImplementation(component, uidl)) {
+ Container parent = getParentLayout(component);
+ if (parent != null) {
+ Widget w = widgetSet.createWidget(uidl);
+ parent.replaceChildComponent(component, w);
+ registerPaintable(uidl.getId(), (Paintable) w);
+ ((Paintable) w).updateFromUIDL(uidl, this);
+ return true;
+ }
+ }
+
+ // Set captions
+ // TODO Manage Error messages
+ if (manageCaption) {
+ Container parent = getParentLayout(component);
+ if (parent != null) {
+ parent.updateCaption((Paintable) component, uidl);
+ }
+ }
+
+ // Styles + disabled & readonly
+ component.setStyleName(component.getStylePrimaryName());
+
+ // first disabling and read-only status
+ boolean enabled = true;
+ if (uidl.hasAttribute("disabled")) {
+ enabled = !uidl.getBooleanAttribute("disabled");
+ } else if (uidl.hasAttribute("readonly")) {
+ enabled = !uidl.getBooleanAttribute("readonly");
+ }
+ if (component instanceof FocusWidget) {
+ ((FocusWidget) component).setEnabled(enabled);
+ }
+ if (!enabled) {
+ component.addStyleName("i-disabled");
+ } else {
+ component.removeStyleName("i-disabled");
+ }
+
+ // add additional styles as css classes, prefixed with component default
+ // stylename
+ if (uidl.hasAttribute("style")) {
+ String[] styles = uidl.getStringAttribute("style").split(" ");
+ for (int i = 0; i < styles.length; i++) {
+ component.addStyleDependentName(styles[i]);
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get either existing or new widget for given UIDL.
+ *
+ * If corresponding paintable has been previously painted, return it.
+ * Otherwise create and register a new widget from UIDL. Caller must update
+ * the returned widget from UIDL after it has been connected to parent.
+ *
+ * @param uidl
+ * UIDL to create widget from.
+ * @return Either existing or new widget corresponding to UIDL.
+ */
+ public Widget getWidget(UIDL uidl) {
+ String id = uidl.getId();
+ Widget w = (Widget) getPaintable(id);
+ if (w != null) {
+ return w;
+ }
+ w = widgetSet.createWidget(uidl);
+ registerPaintable(id, (Paintable) w);
+ return w;
+ }
+
+ public String getResource(String name) {
+ return (String) resourcesMap.get(name);
+ }
+
+ /**
+ * Singleton method to get instance of app's context menu.
+ *
+ * @return IContextMenu object
+ */
+ public ContextMenu getContextMenu() {
+ if (contextMenu == null) {
+ contextMenu = new ContextMenu();
+ }
+ return contextMenu;
+ }
+
+ /**
+ * Translates custom protocols in UIRL URI's to be recognizable by browser.
+ * All uri's from UIDL should be routed via this method before giving them
+ * to browser due URI's in UIDL may contain custom protocols like theme://.
+ *
+ * @param toolkitUri
+ * toolkit URI from uidl
+ * @return translated URI ready for browser
+ */
+ public String translateToolkitUri(String toolkitUri) {
+ if (toolkitUri.startsWith("theme")) {
+ toolkitUri = getThemeUri() + toolkitUri.substring(7);
+ }
+ return toolkitUri;
+ }
}
diff --git a/src/com/itmill/toolkit/terminal/gwt/public/default/common/common.css b/src/com/itmill/toolkit/terminal/gwt/public/default/common/common.css
index 0669aed679..774af35aaa 100644
--- a/src/com/itmill/toolkit/terminal/gwt/public/default/common/common.css
+++ b/src/com/itmill/toolkit/terminal/gwt/public/default/common/common.css
@@ -125,3 +125,20 @@
text-decoration: underline;
cursor:pointer;
}
+
+
+
+/* Loading indicator states */
+.i-loading-indicator,
+.i-loading-indicator-delay,
+.i-loading-indicator-wait {
+ width: 31px;
+ height: 31px;
+ background: transparent url(img/loading-indicator.gif);
+}
+.i-loading-indicator-delay {
+ background: transparent url(img/loading-indicator-delay.gif);
+}
+.i-loading-indicator-wait {
+ background: transparent url(img/loading-indicator-wait.gif);
+} \ No newline at end of file
diff --git a/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/ajax-loader-big.gif b/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/ajax-loader-big.gif
new file mode 100644
index 0000000000..73dc88e31f
--- /dev/null
+++ b/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/ajax-loader-big.gif
Binary files differ
diff --git a/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/ajax-loader-medium.gif b/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/ajax-loader-medium.gif
new file mode 100644
index 0000000000..0a0c6aaef0
--- /dev/null
+++ b/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/ajax-loader-medium.gif
Binary files differ
diff --git a/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/ajax-loader.gif b/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/ajax-loader.gif
index 2c5a7c0a3c..354dc4685c 100755
--- a/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/ajax-loader.gif
+++ b/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/ajax-loader.gif
Binary files differ
diff --git a/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/loading-indicator-delay.gif b/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/loading-indicator-delay.gif
new file mode 100755
index 0000000000..48810bb064
--- /dev/null
+++ b/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/loading-indicator-delay.gif
Binary files differ
diff --git a/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/loading-indicator-wait.gif b/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/loading-indicator-wait.gif
new file mode 100755
index 0000000000..5f7aab9afd
--- /dev/null
+++ b/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/loading-indicator-wait.gif
Binary files differ
diff --git a/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/loading-indicator.gif b/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/loading-indicator.gif
new file mode 100755
index 0000000000..cedaa56b10
--- /dev/null
+++ b/src/com/itmill/toolkit/terminal/gwt/public/default/common/img/loading-indicator.gif
Binary files differ
diff --git a/src/com/itmill/toolkit/terminal/gwt/public/default/table/table.css b/src/com/itmill/toolkit/terminal/gwt/public/default/table/table.css
index 6ff2bd4e1d..3a437a9c0e 100644
--- a/src/com/itmill/toolkit/terminal/gwt/public/default/table/table.css
+++ b/src/com/itmill/toolkit/terminal/gwt/public/default/table/table.css
@@ -168,5 +168,8 @@
/* IE specific styles */
* html .i-table-scrollposition {
background: transparent;
+ /* We need two different filters because we cannot be sure of the context
+ the browser is currently in (i.e. with ending slash or without). */
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../ITMILL/widgetsets/com.itmill.toolkit.terminal.gwt.DefaultWidgetSet/default/table/img/scroll-position-bg.png", sizingMethod="scale");
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="ITMILL/widgetsets/com.itmill.toolkit.terminal.gwt.DefaultWidgetSet/default/table/img/scroll-position-bg.png", sizingMethod="scale");
} \ No newline at end of file
diff --git a/src/com/itmill/toolkit/terminal/gwt/public/default/tabsheet/tabsheet.css b/src/com/itmill/toolkit/terminal/gwt/public/default/tabsheet/tabsheet.css
index d2a11ab5fe..ac1d883e0e 100644
--- a/src/com/itmill/toolkit/terminal/gwt/public/default/tabsheet/tabsheet.css
+++ b/src/com/itmill/toolkit/terminal/gwt/public/default/tabsheet/tabsheet.css
@@ -9,7 +9,8 @@
empty-cells: hide;
border-collapse: collapse;
height: 48px;
- background: transparent url(img/tabs-bg.png) repeat-x bottom left;
+ background: transparent url(img/tabs-bg.png) repeat-x bottom left;
+ width: 100%;
}
.i-tabsheet-tabs .gwt-TabBarFirst {
@@ -120,7 +121,10 @@
.i-tabsheet-loading .i-tabsheet-content * {
visibility: hidden;
overflow: hidden;
-}
+}
+
+
+
/* IE specific styles */
* html .i-tabsheet-content {