1 /****************************************************************************
  2  Copyright (c) 2011-2012 cocos2d-x.org
  3  Copyright (c) 2013-2014 Chukong Technologies Inc.
  4 
  5  http://www.cocos2d-x.org
  6 
  7  Permission is hereby granted, free of charge, to any person obtaining a copy
  8  of this software and associated documentation files (the "Software"), to deal
  9  in the Software without restriction, including without limitation the rights
 10  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 11  copies of the Software, and to permit persons to whom the Software is
 12  furnished to do so, subject to the following conditions:
 13 
 14  The above copyright notice and this permission notice shall be included in
 15  all copies or substantial portions of the Software.
 16 
 17  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 18  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 19  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 20  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 21  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 22  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 23  THE SOFTWARE.
 24  ****************************************************************************/
 25 
 26 /**
 27  * The ImageView control of Cocos GUI
 28  * @class
 29  * @extends ccui.Widget
 30  */
 31 ccui.ImageView = ccui.Widget.extend(/** @lends ccui.ImageView# */{
 32     _scale9Enabled: false,
 33     _prevIgnoreSize: true,
 34     _capInsets: null,
 35     _imageRenderer: null,
 36     _textureFile: "",
 37     _imageTexType: ccui.Widget.LOCAL_TEXTURE,
 38     _imageTextureSize: null,
 39     _className:"ImageView",
 40     _imageRendererAdaptDirty: true,
 41 
 42     /**
 43      * allocates and initializes a ccui.ImageView.
 44      * Constructor of ccui.ImageView, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
 45      * @param {String} imageFileName
 46      * @param {Number} [texType==ccui.Widget.LOCAL_TEXTURE]
 47      * @example
 48      * // example
 49      * var uiImageView = new ccui.ImageView;
 50      */
 51     ctor: function (imageFileName, texType) {
 52         this._capInsets = cc.rect(0,0,0,0);
 53         this._imageTextureSize = cc.size(this._capInsets.width, this._capInsets.height);
 54         ccui.Widget.prototype.ctor.call(this);
 55 
 56         texType && this.init(imageFileName, texType);
 57     },
 58 
 59     /**
 60      * Initializes an imageView. please do not call this function by yourself, you should pass the parameters to constructor to initialize it.
 61      * @param {String} imageFileName
 62      * @param {Number} [texType==ccui.Widget.LOCAL_TEXTURE]
 63      * @returns {boolean}
 64      */
 65     init: function(imageFileName, texType){
 66         if(ccui.Widget.prototype.init.call(this)){
 67             if(imageFileName === undefined)
 68                 this._imageTexType = ccui.Widget.LOCAL_TEXTURE;
 69             else
 70                 this.loadTexture(imageFileName, texType);
 71             return true;
 72         }
 73         return false;
 74     },
 75 
 76     _initRenderer: function () {
 77         this._imageRenderer = cc.Sprite.create();
 78         this.addProtectedChild(this._imageRenderer, ccui.ImageView.RENDERER_ZORDER, -1);
 79     },
 80 
 81     /**
 82      * Loads textures for button.
 83      * @param {String} fileName
 84      * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
 85      */
 86     loadTexture: function (fileName, texType) {
 87         if (!fileName) {
 88             return;
 89         }
 90         var self = this;
 91         texType = texType || ccui.Widget.LOCAL_TEXTURE;
 92         this._textureFile = fileName;
 93         this._imageTexType = texType;
 94         var imageRenderer = self._imageRenderer;
 95 
 96         switch (self._imageTexType) {
 97             case ccui.Widget.LOCAL_TEXTURE:
 98                 if(self._scale9Enabled){
 99                     imageRenderer.initWithFile(fileName);
100                     imageRenderer.setCapInsets(self._capInsets);
101                 }else{
102                     //SetTexture cannot load resource
103                     imageRenderer.initWithFile(fileName);
104                 }
105                 break;
106             case ccui.Widget.PLIST_TEXTURE:
107                 if(self._scale9Enabled){
108                     imageRenderer.initWithSpriteFrameName(fileName);
109                     imageRenderer.setCapInsets(self._capInsets);
110                 }else{
111                     //SetTexture cannot load resource
112                     imageRenderer.initWithSpriteFrameName(fileName);
113                 }
114                 break;
115             default:
116                 break;
117         }
118 
119         if(!imageRenderer.texture || !imageRenderer.texture.isLoaded()){
120             imageRenderer.addLoadedEventListener(function(){
121                 self._findLayout();
122 
123                 self._imageTextureSize = imageRenderer.getContentSize();
124                 self._updateFlippedX();
125                 self._updateFlippedY();
126 
127                 self._updateChildrenDisplayedRGBA();
128 
129                 self._updateContentSizeWithTextureSize(self._imageTextureSize);
130                 self._imageRendererAdaptDirty = true;
131             });
132         }
133 
134         self._imageTextureSize = imageRenderer.getContentSize();
135         self._updateFlippedX();
136         self._updateFlippedY();
137 
138         this._updateChildrenDisplayedRGBA();
139 
140         self._updateContentSizeWithTextureSize(self._imageTextureSize);
141         self._imageRendererAdaptDirty = true;
142     },
143 
144     /**
145      * Sets texture rect
146      * @param {cc.Rect} rect
147      */
148     setTextureRect: function (rect) {
149         if (!this._scale9Enabled)
150             this._imageRenderer.setTextureRect(rect);
151     },
152 
153     _updateFlippedX: function () {
154         if (this._scale9Enabled)
155             this._imageRenderer.setScaleX(this._flippedX ? -1 : 1);
156         else
157             this._imageRenderer.setFlippedX(this._flippedX);
158     },
159 
160     _updateFlippedY: function () {
161         if (this._scale9Enabled)
162             this._imageRenderer.setScaleY(this._flippedY ? -1 : 1);
163         else
164             this._imageRenderer.setFlippedY(this._flippedY);
165     },
166 
167     /**
168      * Sets if button is using scale9 renderer.
169      * @param {Boolean} able
170      */
171     setScale9Enabled: function (able) {
172         if (this._scale9Enabled == able)
173             return;
174 
175         this._scale9Enabled = able;
176         this.removeProtectedChild(this._imageRenderer);
177         this._imageRenderer = null;
178         if (this._scale9Enabled) {
179             this._imageRenderer = new ccui.Scale9Sprite();
180         } else {
181             this._imageRenderer = cc.Sprite.create();
182         }
183         this.loadTexture(this._textureFile, this._imageTexType);
184         this.addProtectedChild(this._imageRenderer, ccui.ImageView.RENDERER_ZORDER, -1);
185         if (this._scale9Enabled) {
186             var ignoreBefore = this._ignoreSize;
187             this.ignoreContentAdaptWithSize(false);
188             this._prevIgnoreSize = ignoreBefore;
189         } else
190             this.ignoreContentAdaptWithSize(this._prevIgnoreSize);
191         this.setCapInsets(this._capInsets);
192     },
193 
194     /**
195      * Returns ImageView is using scale9 renderer or not.
196      * @returns {Boolean}
197      */
198     isScale9Enabled:function(){
199         return this._scale9Enabled;
200     },
201 
202     /**
203      * Ignore the imageView's custom size, true that imageView will ignore it's custom size, use renderer's content size, false otherwise.
204      * @override
205      * @param {Boolean} ignore
206      */
207     ignoreContentAdaptWithSize: function (ignore) {
208         if (!this._scale9Enabled || (this._scale9Enabled && !ignore)) {
209             ccui.Widget.prototype.ignoreContentAdaptWithSize.call(this, ignore);
210             this._prevIgnoreSize = ignore;
211         }
212     },
213 
214     /**
215      * Sets capinsets for button, if button is using scale9 renderer.
216      * @param {cc.Rect} capInsets
217      */
218     setCapInsets: function (capInsets) {
219         if(!capInsets)
220             return;
221         var locInsets = this._capInsets;
222         locInsets.x = capInsets.x;
223         locInsets.y = capInsets.y;
224         locInsets.width = capInsets.width;
225         locInsets.height = capInsets.height;
226 
227         if (!this._scale9Enabled)
228             return;
229         this._imageRenderer.setCapInsets(capInsets);
230     },
231 
232     /**
233      * Returns cap insets of ccui.ImageView.
234      * @returns {cc.Rect}
235      */
236     getCapInsets:function(){
237         return cc.rect(this._capInsets);
238     },
239 
240     _onSizeChanged: function () {
241         ccui.Widget.prototype._onSizeChanged.call(this);
242         this._imageRendererAdaptDirty = true;
243     },
244 
245     _adaptRenderers: function(){
246         if (this._imageRendererAdaptDirty){
247             this._imageTextureScaleChangedWithSize();
248             this._imageRendererAdaptDirty = false;
249         }
250     },
251 
252     /**
253      * Returns the image's texture size.
254      * @returns {cc.Size}
255      */
256     getVirtualRendererSize: function(){
257         return cc.size(this._imageTextureSize);
258     },
259 
260     /**
261      * Returns the renderer of ccui.ImageView
262      * @override
263      * @returns {cc.Node}
264      */
265     getVirtualRenderer: function () {
266         return this._imageRenderer;
267     },
268 
269     _imageTextureScaleChangedWithSize: function () {
270         if (this._ignoreSize) {
271             if (!this._scale9Enabled)
272                 this._imageRenderer.setScale(1.0);
273         } else {
274             if (this._scale9Enabled)
275                 this._imageRenderer.setPreferredSize(this._contentSize);
276             else {
277                 var textureSize = this._imageRenderer.getContentSize();
278                 if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
279                     this._imageRenderer.setScale(1.0);
280                     return;
281                 }
282                 this._imageRenderer.setScaleX(this._contentSize.width / textureSize.width);
283                 this._imageRenderer.setScaleY(this._contentSize.height / textureSize.height);
284             }
285         }
286         this._imageRenderer.setPosition(this._contentSize.width / 2.0, this._contentSize.height / 2.0);
287     },
288 
289     /**
290      * Returns the "class name" of ccui.ImageView.
291      * @override
292      * @returns {string}
293      */
294     getDescription: function () {
295         return "ImageView";
296     },
297 
298     _createCloneInstance:function(){
299         return ccui.ImageView.create();
300     },
301 
302     _copySpecialProperties: function (imageView) {
303         if(imageView instanceof ccui.ImageView){
304             this._prevIgnoreSize = imageView._prevIgnoreSize;
305             this.setScale9Enabled(imageView._scale9Enabled);
306             this.loadTexture(imageView._textureFile, imageView._imageTexType);
307             this.setCapInsets(imageView._capInsets);
308         }
309     }
310 
311 });
312 
313 /**
314  * Allocates and initializes a UIImageView.
315  * @deprecated since v3.0, please use new ccui.ImageView() instead.
316  * @param {string} imageFileName
317  * @param {Number} texType
318  * @return {ccui.ImageView}
319  * @example
320  * // example
321  * var uiImageView = ccui.ImageView.create();
322  */
323 ccui.ImageView.create = function (imageFileName, texType) {
324     return new ccui.ImageView(imageFileName, texType);
325 };
326 
327 // Constants
328 /**
329  * The zOrder value of ccui.ImageView's renderer.
330  * @constant
331  * @type {number}
332  */
333 ccui.ImageView.RENDERER_ZORDER = -1;