UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

256 lines (218 loc) 6.74 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2004-2013 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: * Tino Butz (tbtz) ************************************************************************ */ /** * The image widget displays an image file. * * *Example* * * Here is a little example of how to use the widget. * * <pre class='javascript'> * var image = new qx.ui.mobile.basic.Image("path/to/icon.png"); * * this.getRoot().add(image); * </pre> * * This example create a widget to display the image * <code>path/to/icon.png</code>. * */ qx.Class.define("qx.ui.mobile.basic.Image", { extend: qx.ui.mobile.core.Widget, /* ***************************************************************************** CONSTRUCTOR ***************************************************************************** */ /** * @param source {String?null} The URL of the image to display. */ construct(source) { super(); if (qx.ui.mobile.basic.Image.ROOT === null) { qx.ui.mobile.basic.Image.ROOT = qx.core.Init.getApplication().getRoot(); } if (source) { this.setSource(source); } else { this.initSource(); } qx.ui.mobile.basic.Image.ROOT.addListener( "changeAppScale", this._onChangeAppScale, this ); }, /* ***************************************************************************** EVENTS ***************************************************************************** */ events: { /** * Fired if the image source can not be loaded. */ loadingFailed: "qx.event.type.Event", /** * Fired if the image has been loaded. */ loaded: "qx.event.type.Event" }, statics: { /** @type {qx.ui.mobile.core.Root} the mobile application root */ ROOT: null, /** @type {String} a 1px*1px sized transparent image. */ PLACEHOLDER_IMAGE: null }, /* ***************************************************************************** PROPERTIES ***************************************************************************** */ properties: { /** * The URL of the image to display. */ source: { check: "String", nullable: true, init: null, apply: "_applySource" } }, /* ***************************************************************************** MEMBERS ***************************************************************************** */ members: { // overridden _getTagName() { return "img"; }, // property apply _applySource(value, old) { var resourceManager = qx.util.ResourceManager.getInstance(); var source = value; if (source && source.indexOf("data:") != 0) { var uri = resourceManager.toUri(source); if (resourceManager.has(source)) { var highResSource = resourceManager.findHighResolutionSource( source, qx.ui.mobile.basic.Image.ROOT.getAppScale() ); if (highResSource) { this._createHighResolutionOverlay(highResSource, source); source = qx.ui.mobile.basic.Image.PLACEHOLDER_IMAGE; uri = resourceManager.toUri(highResSource); } else { source = uri; } } if ( !qx.io.ImageLoader.isFailed(uri) && !qx.io.ImageLoader.isLoaded(uri) ) { qx.io.ImageLoader.load(uri, this.__loaderCallback, this); } } this._setSource(source); }, /** * Event handler for "changeAppScale" on application root. * Reloads the image source. */ _onChangeAppScale() { this._applySource(this.getSource()); }, /** * Creates an overlay for this image which shows the image defined by the parameter 'highResSource', * but has the same size and position as the source image. * The original image widget is hidden by this method. * * @param highResSource {String} Image source of the high-resolution image. * @param lowResSource {String} Image source of the low-resolution image. */ _createHighResolutionOverlay(highResSource, lowResSource) { // Replace the source through transparent pixel for making the high-resolution background image visible. var resourceManager = qx.util.ResourceManager.getInstance(); this._setStyle( "backgroundImage", "url(" + resourceManager.toUri(highResSource) + ")" ); this._setStyle("backgroundSize", "100%"); this._setStyle("backgroundRepeat", "no-repeat"); this._setStyle("backgroundPosition", "50% 50%"); this._setStyle( "width", resourceManager.getImageWidth(lowResSource) / 16 + "rem" ); this._setStyle( "height", resourceManager.getImageHeight(lowResSource) / 16 + "rem" ); }, /** * Event handler fired after the preloader has finished loading the icon * * @param source {String} Image source which was loaded * @param imageInfo {Map} Dimensions of the loaded image */ __loaderCallback(source, imageInfo) { // Ignore the callback on already disposed images if (this.$$disposed === true) { return; } // Output a warning if the image could not loaded and quit if (imageInfo.failed) { this.warn("Image could not be loaded: " + source); this.fireEvent("loadingFailed"); } else if (imageInfo.aborted) { // ignore the rest because it is aborted return; } else { this.fireEvent("loaded"); } this._domUpdated(); }, /** * Sets the source attribute of the image tag. * * @param source {String} Image source which was loaded */ _setSource(source) { this._setAttribute("src", source); }, /** * Sets the attribute draggable to the given value "isDraggable". * @param isDraggable {Boolean} target value. */ setDraggable(isDraggable) { if (isDraggable) { this._setAttribute("draggable", "true"); } else { this._setAttribute("draggable", "false"); } } }, defer(statics) { statics.PLACEHOLDER_IMAGE = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"; }, destruct() { qx.ui.mobile.basic.Image.ROOT.removeListener( "changeAppScale", this._onChangeAppScale, this ); } });