UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

180 lines (150 loc) 4.84 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2004-2008 1&1 Internet AG, Germany, http://www.1und1.de License: MIT: https://opensource.org/licenses/MIT See the LICENSE file in the project's top-level directory for details. Authors: * Sebastian Werner (wpbasti) ************************************************************************ */ /** * Keeps data about the visibility of all widgets. Updates the internal * tree when widgets are added, removed or modify their visibility. */ qx.Class.define("qx.ui.core.queue.Visibility", { statics : { /** @type {Array} This contains all the queued widgets for the next flush. */ __queue : [], /** @type {Map} map of widgets by hash code which are in the queue */ __lookup : {}, /** @type {Map} Maps hash codes to visibility */ __data : {}, /** * Clears the cached data of the given widget. Normally only used * during interims disposes of one or a few widgets. * * @param widget {qx.ui.core.Widget} The widget to clear */ remove : function(widget) { if (this.__lookup[widget.$$hash]) { delete this.__lookup[widget.$$hash]; qx.lang.Array.remove(this.__queue, widget); } delete this.__data[widget.$$hash]; }, /** * Whether the given widget is visible. * * Please note that the information given by this method is queued and may not be accurate * until the next queue flush happens. * * @param widget {qx.ui.core.Widget} The widget to query * @return {Boolean} Whether the widget is visible */ isVisible : function(widget) { return this.__data[widget.$$hash] || false; }, /** * Computes the visibility for the given widget * * @param widget {qx.ui.core.Widget} The widget to update * @return {Boolean} Whether the widget is visible */ __computeVisible : function(widget) { var data = this.__data; var hash = widget.$$hash; var visible; // Respect local value if (widget.isExcluded()) { visible = false; } else { // Parent hierarchy var parent = widget.$$parent; if (parent) { visible = this.__computeVisible(parent); } else { visible = widget.isRootWidget(); } } return data[hash] = visible; }, /** * Adds a widget to the queue. * * Should only be used by {@link qx.ui.core.Widget}. * * @param widget {qx.ui.core.Widget} The widget to add. */ add : function(widget) { if (this.__lookup[widget.$$hash]) { return; } this.__queue.unshift(widget); this.__lookup[widget.$$hash] = widget; qx.ui.core.queue.Manager.scheduleFlush("visibility"); }, /** * Flushes the visibility queue. * * This is used exclusively by the {@link qx.ui.core.queue.Manager}. */ flush : function() { // Dispose all registered objects var queue = this.__queue; var data = this.__data; // Dynamically add children to queue // Only respect already known widgets because otherwise the children // are also already in the queue (added on their own) for (var i = queue.length - 1; i >= 0; i--) { var hash = queue[i].$$hash; if (data[hash] != null) { // recursive method call which adds widgets to the queue so be // careful with that one (performance critical) queue[i].addChildrenToQueue(queue); } } // Cache old data, clear current data // Do this before starting with recomputation because // new data may also be added by related widgets and not // only the widget itself. var oldData = {}; for (var i = queue.length - 1; i >= 0; i--) { var hash = queue[i].$$hash; oldData[hash] = data[hash]; data[hash] = null; } // Finally recompute for (var i = queue.length - 1; i >= 0; i--) { var widget = queue[i]; var hash = widget.$$hash; queue.splice(i, 1); // Only update when not already updated by another widget if (data[hash] == null) { this.__computeVisible(widget); } // Check for updates required to the appearance. // Hint: Invisible widgets are ignored inside appearance flush if (data[hash] && data[hash] != oldData[hash]) { widget.checkAppearanceNeeds(); } } // Recreate the array is cheaper compared to keep a sparse array over time this.__queue = []; this.__lookup = {}; } } });