001/*
002 * #%L
003 * GwtMaterial
004 * %%
005 * Copyright (C) 2015 - 2017 GwtMaterialDesign
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 * 
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 * 
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package gwt.material.design.themes.client;
021
022import com.google.gwt.core.client.GWT;
023import com.google.gwt.core.client.RunAsyncCallback;
024import com.google.gwt.dom.client.Element;
025import com.google.gwt.dom.client.StyleInjector;
026import com.google.gwt.resources.client.ClientBundle;
027import com.google.gwt.resources.client.TextResource;
028
029import java.util.ArrayList;
030import java.util.List;
031
032/**
033 * Simple asynchronous loader for our preset themes.
034 * @author Ben Dol
035 */
036public class ThemeLoader {
037
038    public interface ThemeAsyncCallback {
039        /**
040         * Called once the necessary code for it has been loaded.
041         * @param resourceCount The total number of resources loaded.
042         */
043        void onSuccess(int resourceCount);
044
045        /**
046         * Called when, for some reason, the necessary code cannot be loaded. For
047         * example, the web browser might no longer have network access.
048         */
049        void onFailure(Throwable reason);
050    }
051
052    public interface ThemeBundle extends ClientBundle {
053        TextResource style();
054        TextResource overrides();
055    }
056
057    private static List<Element> elements;
058
059    /**
060     * Load a provided {@link ThemeBundle} asynchronously.
061     *
062     * @param bundle The required theme bundle.
063     * @param callback The async callback.
064     */
065    public static void loadAsync(final ThemeBundle bundle, final ThemeAsyncCallback callback) {
066        GWT.runAsync(new RunAsyncCallback() {
067            @Override
068            public void onSuccess() {
069                if(bundle != null) {
070                    if(elements == null) {
071                        elements = new ArrayList<>();
072                    } else {
073                        unload();
074                    }
075
076                    // More resources might be loaded in the future.
077                    elements.add(StyleInjector.injectStylesheet(bundle.style().getText()));
078                    elements.add(StyleInjector.injectStylesheet(bundle.overrides().getText()));
079                }
080
081                if(callback != null) {
082                    callback.onSuccess(elements.size());
083                }
084            }
085            @Override
086            public void onFailure(Throwable reason) {
087                if(callback != null) {
088                    callback.onFailure(reason);
089                }
090            }
091        });
092    }
093
094    /**
095     * Unload the current loaded theme.
096     */
097    public static void unload() {
098        if(elements != null) {
099            for (Element style : elements) {
100                style.removeFromParent();
101            }
102            elements.clear();
103        }
104    }
105}