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