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         texType = texType === undefined ? 0 : texType;
 56 
 57         if(imageFileName) {
 58             this.loadTexture(imageFileName, texType);
 59         }
 60         else {
 61             this._imageTexType = ccui.Widget.LOCAL_TEXTURE;
 62         }
 63     },
 64 
 65     _initRenderer: function () {
 66         //todo create Scale9Sprite and setScale9Enabled(false)
 67         this._imageRenderer = new cc.Sprite();
 68         this.addProtectedChild(this._imageRenderer, ccui.ImageView.RENDERER_ZORDER, -1);
 69     },
 70 
 71     /**
 72      * Loads textures for button.
 73      * @param {String} fileName
 74      * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
 75      */
 76     loadTexture: function (fileName, texType) {
 77         //todo use this code when _initRenderer use Scale9Sprite
 78         //if (!fileName || (this._textureFile == fileName && this._imageTexType == texType)) {
 79         if (!fileName) {
 80             return;
 81         }
 82         var self = this;
 83         texType = texType || ccui.Widget.LOCAL_TEXTURE;
 84         this._textureFile = fileName;
 85         this._imageTexType = texType;
 86         var imageRenderer = self._imageRenderer;
 87 
 88         if(!imageRenderer._textureLoaded){
 89             imageRenderer.addEventListener("load", function(){
 90                 self.loadTexture(self._textureFile, self._imageTexType);
 91             });
 92         }
 93 
 94         switch (self._imageTexType) {
 95             case ccui.Widget.LOCAL_TEXTURE:
 96                 if(self._scale9Enabled){
 97                     imageRenderer.initWithFile(fileName);
 98                     imageRenderer.setCapInsets(self._capInsets);
 99                 }else{
100                     //SetTexture cannot load resource
101                     imageRenderer.initWithFile(fileName);
102                 }
103                 break;
104             case ccui.Widget.PLIST_TEXTURE:
105                 if(self._scale9Enabled){
106                     imageRenderer.initWithSpriteFrameName(fileName);
107                     imageRenderer.setCapInsets(self._capInsets);
108                 }else{
109                     //SetTexture cannot load resource
110                     imageRenderer.initWithSpriteFrameName(fileName);
111                 }
112                 break;
113             default:
114                 break;
115         }
116 
117         self._imageTextureSize = imageRenderer.getContentSize();
118 
119         this._updateChildrenDisplayedRGBA();
120 
121         self._updateContentSizeWithTextureSize(self._imageTextureSize);
122         self._imageRendererAdaptDirty = true;
123         self._findLayout();
124 
125     },
126 
127     /**
128      * Sets texture rect
129      * @param {cc.Rect} rect
130      */
131     setTextureRect: function (rect) {
132         if (!this._scale9Enabled)
133             this._imageRenderer.setTextureRect(rect);
134     },
135 
136     /**
137      * Sets if button is using scale9 renderer.
138      * @param {Boolean} able
139      */
140     setScale9Enabled: function (able) {
141         //todo setScale9Enabled
142         if (this._scale9Enabled === able)
143             return;
144 
145         this._scale9Enabled = able;
146         this.removeProtectedChild(this._imageRenderer);
147         this._imageRenderer = null;
148         if (this._scale9Enabled) {
149             this._imageRenderer = new ccui.Scale9Sprite();
150         } else {
151             this._imageRenderer = new cc.Sprite();
152         }
153         this.loadTexture(this._textureFile, this._imageTexType);
154         this.addProtectedChild(this._imageRenderer, ccui.ImageView.RENDERER_ZORDER, -1);
155         if (this._scale9Enabled) {
156             var ignoreBefore = this._ignoreSize;
157             this.ignoreContentAdaptWithSize(false);
158             this._prevIgnoreSize = ignoreBefore;
159         } else
160             this.ignoreContentAdaptWithSize(this._prevIgnoreSize);
161         this.setCapInsets(this._capInsets);
162         this._imageRendererAdaptDirty = true;
163     },
164 
165     /**
166      * Returns ImageView is using scale9 renderer or not.
167      * @returns {Boolean}
168      */
169     isScale9Enabled:function(){
170         return this._scale9Enabled;
171     },
172 
173     /**
174      * Ignore the imageView's custom size, true that imageView will ignore it's custom size, use renderer's content size, false otherwise.
175      * @override
176      * @param {Boolean} ignore
177      */
178     ignoreContentAdaptWithSize: function (ignore) {
179         if (!this._scale9Enabled || (this._scale9Enabled && !ignore)) {
180             ccui.Widget.prototype.ignoreContentAdaptWithSize.call(this, ignore);
181             this._prevIgnoreSize = ignore;
182         }
183     },
184 
185     /**
186      * Sets capinsets for button, if button is using scale9 renderer.
187      * @param {cc.Rect} capInsets
188      */
189     setCapInsets: function (capInsets) {
190         if(!capInsets)
191             return;
192         var locInsets = this._capInsets;
193         locInsets.x = capInsets.x;
194         locInsets.y = capInsets.y;
195         locInsets.width = capInsets.width;
196         locInsets.height = capInsets.height;
197 
198         if (!this._scale9Enabled)
199             return;
200         this._imageRenderer.setCapInsets(capInsets);
201     },
202 
203     /**
204      * Returns cap insets of ccui.ImageView.
205      * @returns {cc.Rect}
206      */
207     getCapInsets:function(){
208         return cc.rect(this._capInsets);
209     },
210 
211     _onSizeChanged: function () {
212         ccui.Widget.prototype._onSizeChanged.call(this);
213         this._imageRendererAdaptDirty = true;
214     },
215 
216     _adaptRenderers: function(){
217         if (this._imageRendererAdaptDirty){
218             this._imageTextureScaleChangedWithSize();
219             this._imageRendererAdaptDirty = false;
220         }
221     },
222 
223     /**
224      * Returns the image's texture size.
225      * @returns {cc.Size}
226      */
227     getVirtualRendererSize: function(){
228         return cc.size(this._imageTextureSize);
229     },
230 
231     /**
232      * Returns the renderer of ccui.ImageView
233      * @override
234      * @returns {cc.Node}
235      */
236     getVirtualRenderer: function () {
237         return this._imageRenderer;
238     },
239 
240     _imageTextureScaleChangedWithSize: function () {
241         if (this._ignoreSize) {
242             if (!this._scale9Enabled)
243                 this._imageRenderer.setScale(1.0);
244         } else {
245             if (this._scale9Enabled){
246                 this._imageRenderer.setPreferredSize(this._contentSize);
247                 this._imageRenderer.setScale(1);
248             } else {
249                 var textureSize = this._imageTextureSize;
250                 if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
251                     this._imageRenderer.setScale(1.0);
252                     return;
253                 }
254                 this._imageRenderer.setScaleX(this._contentSize.width / textureSize.width);
255                 this._imageRenderer.setScaleY(this._contentSize.height / textureSize.height);
256             }
257         }
258         this._imageRenderer.setPosition(this._contentSize.width / 2.0, this._contentSize.height / 2.0);
259     },
260 
261     /**
262      * Returns the "class name" of ccui.ImageView.
263      * @override
264      * @returns {string}
265      */
266     getDescription: function () {
267         return "ImageView";
268     },
269 
270     _createCloneInstance:function(){
271         return new ccui.ImageView();
272     },
273 
274     _copySpecialProperties: function (imageView) {
275         if(imageView instanceof ccui.ImageView){
276             this._prevIgnoreSize = imageView._prevIgnoreSize;
277             this.setScale9Enabled(imageView._scale9Enabled);
278             this.loadTexture(imageView._textureFile, imageView._imageTexType);
279             this.setCapInsets(imageView._capInsets);
280         }
281     },
282     /**
283      * Sets _customSize of ccui.Widget, if ignoreSize is true, the content size is its renderer's contentSize, otherwise the content size is parameter.
284      * and updates size percent by parent content size. At last, updates its children's size and position.
285      * @param {cc.Size|Number} contentSize content size or width of content size
286      * @param {Number} [height]
287      * @override
288      */
289     setContentSize: function(contentSize, height){
290         if(height != null)
291             contentSize = cc.size(contentSize, height);
292         ccui.Widget.prototype.setContentSize.call(this, contentSize);
293         if(!this._scale9Enabled){
294             var iContentSize = this._imageRenderer.getContentSize();
295             this._imageRenderer.setScaleX(contentSize.width / iContentSize.width);
296             this._imageRenderer.setScaleY(contentSize.height / iContentSize.height);
297         }else{
298             this._imageRenderer.setContentSize(contentSize);
299         }
300 
301     }
302 
303 });
304 
305 /**
306  * Allocates and initializes a UIImageView.
307  * @deprecated since v3.0, please use new ccui.ImageView() instead.
308  * @param {string} imageFileName
309  * @param {Number} texType
310  * @return {ccui.ImageView}
311  */
312 ccui.ImageView.create = function (imageFileName, texType) {
313     return new ccui.ImageView(imageFileName, texType);
314 };
315 
316 // Constants
317 /**
318  * The zOrder value of ccui.ImageView's renderer.
319  * @constant
320  * @type {number}
321  */
322 ccui.ImageView.RENDERER_ZORDER = -1;
323