Source: api/SpwWidgetsManager.js

Retour à la documentation
define(["dojo/_base/declare", "spw/api/SpwMap", "spw/api/ConfigLoader", "dojo/_base/array", "dojo/_base/lang",
        "dojo/Evented", "spw/api/Utils", "dojo/Deferred"],
        function(declare, SpwMap, ConfigLoader, array, lang, Evented, Utils, Deferred){
    var SpwWidgetsManager = null;
    SpwWidgetsManager = declare("spw.api.SpwWidgetsManager", [Evented], /** @lends spw.api.SpwWidgetsManager.prototype */{
        /**
         * Tableau des différents outils chargés
         * @private
         * @type spw.api.SpwBaseWidget[]
         */
        _widgets: null,
        _widgetClasses: null,
        _widgetsConfig: null,

        /**
         * Référence vers le viewer.
         */
        spwViewer: null,

        /**
         * Indique si toutes les classes des widgets sont chargées.
         * @type Boolean
         */
        widgetClassesLoaded: null,

        /**
         * Indique si tous les widgets sont instanciés.
         * @type Boolean
         */
        widgetsCreated: null,

        events: {},

        /**
         * @constructs
         * @classdesc Cette classe est un singleton et permet d'instancier les widgets déclarés dans le fichier widgets.json. De plus, elle offre des méthode permettant d'accéder aux widgets.
         */
        constructor: function(config) {
            this._widgets = {};

            this.spwViewer = config.spwViewer;

            this.widgetClassesLoaded = false;
            lang.mixin(this.events, SpwWidgetsManager.events);
        },

        /**
         * Charge dynamiquement les classes (code javascript) des widgets déclarés dans widgets.json.
         */
        loadWidgetClasses: function(defaultWidgets) {
        	if(defaultWidgets) {
        		this.defaultWidgets = defaultWidgets = [].concat(defaultWidgets);
            }

            this._widgetClasses = {};
            this._widgetsConfig = ConfigLoader.getInstance().get("widgets");

            array.forEach(this.defaultWidgets, lang.hitch(this, function(w) {
                if (w == null || w.config == null || w.config.widgetId == null) {
                    return;
                }

                var found = array.some(this._widgetsConfig, lang.hitch(this, function(cfg) {
                    return cfg && cfg.config && cfg.config.widgetId === w.config.widgetId;
                }));

                if (!found) {
                	//if(!w.config.configSecondScreen || w.config.configSecondScreen.create !== false || !this.spwViewer.isSideWindow()){
                        this._widgetsConfig.push(w);
                	//}
                }
                
                //remove all widget with create = false
                this._widgetsConfig = array.filter(this._widgetsConfig, lang.hitch(this, function(w){	
                	return !w.config || (!w.config.configSecondScreen || w.config.configSecondScreen.create !== false || !this.spwViewer.isSideWindow());
                }));
            }));

            this._widgetsConfig.sort(function(w1, w2) {
                if (w1.order == null && w2.order == null) {
                    return 0;
                }

                if (w1.order === 'last') { return 1; }
                if (w2.order === 'last') { return -1; }

                if (w1.order == null && w2.order !== null && typeof(w2.order) !== 'undefined') {
                    return 1;
                }

                if (w2.order == null && w1.order !== null && typeof(w1.order) !== 'undefined') {
                    return -1;
                }

                // dans le cas où 2 infinis -> une soustraction ne fonctionnera pas
                if (w1.order < w2.order) {
                    return -1;
                }
                else if (w1.order > w2.order) {
                    return 1;
                }

                return 0;
            });
            
            if (!this._widgetsConfig || this._widgetsConfig.length == 0) {
                this.widgetClassesLoaded = true;
                this.emit(SpwWidgetsManager.events.widgetClassesLoaded);
                this.widgetsCreated = true;
                this.emit(SpwWidgetsManager.events.widgetsCreated);
                return;
            }

            var cpt = 0;
            var handler = null;
            handler = require.on("error", lang.hitch(this, function(err){
                cpt++;
                if(cpt == this._widgetsConfig.length){
                    handler.remove();
                    this.widgetClassesLoaded = true;
                    this.emit(SpwWidgetsManager.events.widgetClassesLoaded);
                }
                if(++this._instanciateCount == this._widgetsConfig.length){
                    this.widgetsCreated = true;
                    this._instanciateCount = 0;
                    this.emit(SpwWidgetsManager.events.widgetsCreated);
                }
            }));

            this.calculateToolbarIndexes();

            var loadWidgetFunc = function(cfg, i, def) {
                if (typeof cfg === 'string') {
                    cfg = {className: cfg};
                }

                require([cfg.className], lang.hitch(this, function(WidgetClass){
                    if(!cfg.config){
                        cfg.config = {};
                    }

                    cpt++;

                    lang.mixin(cfg.config, {spwViewer: this.spwViewer});
                    this._widgetClasses[i] = lang.mixin({}, {widgetClass: WidgetClass, widgetConfig: cfg.config});

                    this.instanciateWidget(this._widgetClasses[i]);

                    if(cpt == this._widgetsConfig.length) {
                        handler.remove();
                        this.widgetClassesLoaded = true;
                        this.emit(SpwWidgetsManager.events.widgetClassesLoaded);
                    }

                    def && def.resolve();
                }));
            };

            var defs = [new Deferred().resolve()];
            var stoppedIdx = this._widgetsConfig.length;

            array.every(this._widgetsConfig, lang.hitch(this, function(widgetConfig, idx) {
                if (widgetConfig.order == null) {
                    stoppedIdx = idx;
                    return false;
                }

                var def = new Deferred();
                defs.push(def);
                defs[idx].then(lang.hitch(this, loadWidgetFunc, widgetConfig, idx, def));
                return true;
            }));

            defs[stoppedIdx].then(lang.hitch(this, function() {
                for (; stoppedIdx < this._widgetsConfig.length; ++stoppedIdx) {
                    lang.hitch(this, loadWidgetFunc)(this._widgetsConfig[stoppedIdx], stoppedIdx);
                }
            }));
        },

        /**
         * Instancie les widgets chargés.
         */
        instanciateWidgets: function() {
            for(var key in this._widgetClasses){
                var w = this._widgetClasses[key];
                this.instanciateWidget(w);
            };
        },

        _instanciateCount: 0,

        /**
         * Instancie un widget
         * @param w le widget à créer
         */
        instanciateWidget: function(w) {
            try {
                if(typeof w.widgetClass != 'undefined'){
                    var widget = null;
                    if(w.widgetConfig.inToolbar){
                        widget = new w.widgetClass(w.widgetConfig);
                        this.spwViewer.addWidgetInToolbar(widget);
                    } else {
                        widget = new w.widgetClass(w.widgetConfig);
                    }

                    if (widget.widgetId == null) {
                        widget.widgetId = Utils.guid();
                    }

                    this._widgets[widget.widgetId] = widget;

                    return widget;
                }
            } catch(err){
                console.error("Error while instanciating widget " + ((w && w.widgetClass && w.widgetClass.prototype) ? "["+w.widgetClass.prototype.declaredClass+"]" : "[???]"), err);
            } finally {
                if (this._widgetsConfig && this._widgetsConfig.length > 0) {
                    if(++this._instanciateCount == this._widgetsConfig.length){
                        this.widgetsCreated = true;
                        this._instanciateCount = 0;
                        this.emit(SpwWidgetsManager.events.widgetsCreated);
                    }
                }
            }

            return null;
        },

        /**
         * Détruit tous les widgets du viewer.
         */
        destroyWidgets: function() {
            var widget = null;
            
            var tab=[];
            for (var key in this._widgets) { if (this._widgets.hasOwnProperty(key)) tab.push(this._widgets[key]); }
            tab.sort(function(w1, w2) {
                if (w1.order === w2.order) { return 0; }
                if (w1.order === 'last') { return 1; }
                if (w2.order === 'last') { return -1; }
                if (w1.order == null && w2.order == null) { return 0; }
                if (w1.order == null && w2.order !== null && typeof(w2.order) !== 'undefined') { return 1; }
                if (w2.order == null && w1.order !== null && typeof(w1.order) !== 'undefined') { return -1; }
                if (w1.order < w2.order) { return -1; }
                else if (w1.order > w2.order) { return 1; }
                return 0;
            });
            for (var i=tab.length-1; i >= 0; i--) {
                widget = tab[i];
                if(widget.get('inToolbar') || widget.get('position') == 'toolbar'){
                    this.spwViewer.removeWidgetFromToolbar(widget);
                }
                if(widget.onDeactivate){
                    widget.onDeactivate();
                }
                this.spwViewer.hideWidget(widget);
                widget.destroy();
            }    
            
            if(this.spwViewer.toolbar){
            	this.spwViewer.toolbar = null;
            }
            this._widgets = {};
        },

        /**
         * Calcul l'index de position dans la toolbar pour les widgets placés dans la toolbar.
         */
        calculateToolbarIndexes: function(){
            var toolWidgetsArray = [];
            array.forEach(this._widgetsConfig, lang.hitch(this, function(wConfig){
                if(wConfig.config && (wConfig.config.inToolbar || wConfig.config.position == "toolbar")){
                    toolWidgetsArray.push(wConfig.config);
                }
            }));

            array.forEach(toolWidgetsArray, function(config, idx){
                lang.mixin(config, {toolBarIndex: idx});
            });
        },

        /**
         * Récupère le(s) widget(s) sur base d'un objet clé-valeur. Par exemple: récupérer les widgets actifs : getWidgets({activated:true}) ; récupérer un widget par son id : getWidgets({widgetId:'monWidget'}); ...
         * Toutes les propriétés d'un widget peuvent être interrogées via ce query object. Un Query object vide ({}) permet de récupérer tous les widgets.
         * @param queryObject
         * @returns {Array} Tableau contenant les widgets correspondants à la query.
         */
        getWidgets: function(queryObject) {
            return Utils.findInObject(this._widgets, queryObject);
        },

        /**
         * Accède à un widget sur base de son id
         * @param id l'id du widget auquel accéder
         */
        getWidget: function(id) {
            return this._widgets[id];
        },

        /**
         * Appelé à la destruction du Manager
         */
        destroy: function(){
            this.inherited(arguments);
        }
    });

    SpwWidgetsManager.events = {
        /**
         * Les classes des widgets présents dans la configuration (widgets.json) sont chargées (!= instanciées).
         * @event spw.api.SpwWidgetsManager#widgetClassesLoaded
         */
        "widgetClassesLoaded": "widgetClassesLoaded",
        /**
         * Les widgets sont créés et placé dans le Viewer.
         * @event spw.api.SpwWidgetsManager#widgetsCreated
         */
        "widgetsCreated": "widgetsCreated"
    };

    return SpwWidgetsManager;
});