Created
June 26, 2017 10:22
-
-
Save esidegallery/de6383116ca320275f72b0dcf81215cc to your computer and use it in GitHub Desktop.
Adds texturePreferredWidth and texturePreferredHeight properties to feathers.controls.ImageLoader so that PoT textures can work with all scaleMode and maintainAspectRatio values.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package feathers.controls | |
{ | |
import flash.geom.Rectangle; | |
import feathers.layout.HorizontalAlign; | |
import feathers.layout.VerticalAlign; | |
import starling.display.Quad; | |
import starling.utils.RectangleUtil; | |
import starling.utils.ScaleMode; | |
public class ExtendedImageLoader extends ImageLoader | |
{ | |
private static const INVALIDATION_FLAG_TEXTURE_PREFERRED_SIZE:String = "texturePreferredSize"; | |
private static const HELPER_RECTANGLE:Rectangle = new Rectangle; | |
private static const HELPER_RECTANGLE2:Rectangle = new Rectangle; | |
protected var _textureScaleMultiplierX:Number = 1; | |
protected var _textureScaleMultiplierY:Number = 1; | |
private var _texturePreferredWidth:Number = NaN; | |
public function get texturePreferredWidth():Number | |
{ | |
return _texturePreferredWidth; | |
} | |
public function set texturePreferredWidth(value:Number):void | |
{ | |
if (_texturePreferredWidth != value) | |
{ | |
_texturePreferredWidth = value; | |
invalidate(INVALIDATION_FLAG_TEXTURE_PREFERRED_SIZE); | |
} | |
} | |
private var _texturePreferredHeight:Number = NaN; | |
public function get texturePreferredHeight():Number | |
{ | |
return _texturePreferredHeight; | |
} | |
public function set texturePreferredHeight(value:Number):void | |
{ | |
if (_texturePreferredHeight != value) | |
{ | |
_texturePreferredHeight = value; | |
invalidate(INVALIDATION_FLAG_TEXTURE_PREFERRED_SIZE); | |
} | |
} | |
protected function calculateTextureScaleMultipliers():void | |
{ | |
var newX:Number; | |
if (_texturePreferredWidth > 0 && _currentTextureWidth > 0) | |
newX = _texturePreferredWidth / _currentTextureWidth; | |
else | |
newX = 1; | |
var newY:Number; | |
if (_texturePreferredHeight > 0 && _currentTextureHeight > 0) | |
newY = _texturePreferredHeight / _currentTextureHeight; | |
else | |
newY = 1; | |
if (_textureScaleMultiplierX != newX || _textureScaleMultiplierY != newY) | |
invalidate(INVALIDATION_FLAG_SIZE); | |
_textureScaleMultiplierX = newX; | |
_textureScaleMultiplierY = newY; | |
} | |
override protected function draw():void | |
{ | |
if (isInvalid(INVALIDATION_FLAG_TEXTURE_PREFERRED_SIZE)) | |
calculateTextureScaleMultipliers(); | |
super.draw(); | |
} | |
override protected function autoSizeIfNeeded():Boolean | |
{ | |
var needsWidth:Boolean = this._explicitWidth !== this._explicitWidth; //isNaN | |
var needsHeight:Boolean = this._explicitHeight !== this._explicitHeight; //isNaN | |
var needsMinWidth:Boolean = this._explicitMinWidth !== this._explicitMinWidth; //isNaN | |
var needsMinHeight:Boolean = this._explicitMinHeight !== this._explicitMinHeight; //isNaN | |
if(!needsWidth && !needsHeight && !needsMinWidth && !needsMinHeight) | |
{ | |
return false; | |
} | |
var heightScale:Number = 1; | |
var widthScale:Number = 1; | |
var textureScaleX:Number = textureScale * _textureScaleMultiplierX; | |
var textureScaleY:Number = textureScale * _textureScaleMultiplierY; | |
if(this.scaleContent && this.maintainAspectRatio && | |
this.scaleMode !== ScaleMode.NONE && | |
this.scale9Grid === null) | |
{ | |
if(!needsHeight) | |
{ | |
heightScale = this._explicitHeight / (this._currentTextureHeight * textureScaleY); | |
} | |
else if(this._explicitMaxHeight < this._currentTextureHeight) | |
{ | |
heightScale = this._explicitMaxHeight / (this._currentTextureHeight * textureScaleY); | |
} | |
else if(this._explicitMinHeight > this._currentTextureHeight) | |
{ | |
heightScale = this._explicitMinHeight / (this._currentTextureHeight * textureScaleY); | |
} | |
if(!needsWidth) | |
{ | |
widthScale = this._explicitWidth / (this._currentTextureWidth * textureScaleX); | |
} | |
else if(this._explicitMaxWidth < this._currentTextureWidth) | |
{ | |
widthScale = this._explicitMaxWidth / (this._currentTextureWidth * textureScaleX); | |
} | |
else if(this._explicitMinWidth > this._currentTextureWidth) | |
{ | |
widthScale = this._explicitMinWidth / (this._currentTextureWidth * textureScaleX); | |
} | |
} | |
var newWidth:Number = this._explicitWidth; | |
if(needsWidth) | |
{ | |
if(this._currentTextureWidth === this._currentTextureWidth) //!isNaN | |
{ | |
newWidth = this._currentTextureWidth * textureScaleX * heightScale; | |
} | |
else | |
{ | |
newWidth = 0; | |
} | |
newWidth += this._paddingLeft + this._paddingRight; | |
} | |
var newHeight:Number = this._explicitHeight; | |
if(needsHeight) | |
{ | |
if(this._currentTextureHeight === this._currentTextureHeight) //!isNaN | |
{ | |
newHeight = this._currentTextureHeight * textureScaleY * widthScale; | |
} | |
else | |
{ | |
newHeight = 0; | |
} | |
newHeight += this._paddingTop + this._paddingBottom; | |
} | |
//this ensures that an ImageLoader can recover from width or height | |
//being set to 0 by percentWidth or percentHeight | |
if(needsHeight && needsMinHeight) | |
{ | |
//if no height values are set, use the original texture width | |
//for the minWidth | |
heightScale = 1; | |
} | |
if(needsWidth && needsMinWidth) | |
{ | |
//if no width values are set, use the original texture height | |
//for the minHeight | |
widthScale = 1; | |
} | |
var newMinWidth:Number = this._explicitMinWidth; | |
if(needsMinWidth) | |
{ | |
if(this._currentTextureWidth === this._currentTextureWidth) //!isNaN | |
{ | |
newMinWidth = this._currentTextureWidth * textureScaleX * heightScale; | |
} | |
else | |
{ | |
newMinWidth = 0; | |
} | |
newMinWidth += this._paddingLeft + this._paddingRight; | |
} | |
var newMinHeight:Number = this._explicitMinHeight; | |
if(needsMinHeight) | |
{ | |
if(this._currentTextureHeight === this._currentTextureHeight) //!isNaN | |
{ | |
newMinHeight = this._currentTextureHeight * textureScaleY * widthScale; | |
} | |
else | |
{ | |
newMinHeight = 0; | |
} | |
newMinHeight += this._paddingTop + this._paddingBottom; | |
} | |
return this.saveMeasurements(newWidth, newHeight, newMinWidth, newMinHeight); | |
} | |
override protected function layout():void | |
{ | |
if(!this.image || !this._currentTexture) | |
{ | |
return; | |
} | |
if(this.scaleContent) | |
{ | |
if(this.maintainAspectRatio && this.scale9Grid === null) | |
{ | |
HELPER_RECTANGLE.x = 0; | |
HELPER_RECTANGLE.y = 0; | |
HELPER_RECTANGLE.width = this._currentTextureWidth * this.textureScale * this._textureScaleMultiplierX; | |
HELPER_RECTANGLE.height = this._currentTextureHeight * this.textureScale * this._textureScaleMultiplierY; | |
HELPER_RECTANGLE2.x = 0; | |
HELPER_RECTANGLE2.y = 0; | |
HELPER_RECTANGLE2.width = this.actualWidth - this._paddingLeft - this._paddingRight; | |
HELPER_RECTANGLE2.height = this.actualHeight - this._paddingTop - this._paddingBottom; | |
RectangleUtil.fit(HELPER_RECTANGLE, HELPER_RECTANGLE2, this.scaleMode, false, HELPER_RECTANGLE); | |
this.image.x = HELPER_RECTANGLE.x + this._paddingLeft; | |
this.image.y = HELPER_RECTANGLE.y + this._paddingTop; | |
this.image.width = HELPER_RECTANGLE.width; | |
this.image.height = HELPER_RECTANGLE.height; | |
} | |
else | |
{ | |
this.image.x = this._paddingLeft; | |
this.image.y = this._paddingTop; | |
this.image.width = this.actualWidth - this._paddingLeft - this._paddingRight; | |
this.image.height = this.actualHeight - this._paddingTop - this._paddingBottom; | |
} | |
} | |
else | |
{ | |
var imageWidth:Number = this._currentTextureWidth * this.textureScale * this._textureScaleMultiplierX; | |
var imageHeight:Number = this._currentTextureHeight * this.textureScale * this._textureScaleMultiplierY; | |
if(this._horizontalAlign === HorizontalAlign.RIGHT) | |
{ | |
this.image.x = this.actualWidth - this._paddingRight - imageWidth; | |
} | |
else if(this._horizontalAlign === HorizontalAlign.CENTER) | |
{ | |
this.image.x = this._paddingLeft + ((this.actualWidth - this._paddingLeft - this._paddingRight) - imageWidth) / 2; | |
} | |
else //left | |
{ | |
this.image.x = this._paddingLeft; | |
} | |
if(this._verticalAlign === VerticalAlign.BOTTOM) | |
{ | |
this.image.y = this.actualHeight - this._paddingBottom - imageHeight; | |
} | |
else if(this._verticalAlign === VerticalAlign.MIDDLE) | |
{ | |
this.image.y = this._paddingTop + ((this.actualHeight - this._paddingTop - this._paddingBottom) - imageHeight) / 2; | |
} | |
else //top | |
{ | |
this.image.y = this._paddingTop; | |
} | |
this.image.width = imageWidth; | |
this.image.height = imageHeight; | |
} | |
if((!this.scaleContent || (this.maintainAspectRatio && this.scaleMode !== ScaleMode.SHOW_ALL)) && | |
(this.actualWidth != imageWidth || this.actualHeight != imageHeight)) | |
{ | |
var mask:Quad = this.image.mask as Quad; | |
if(mask !== null) | |
{ | |
mask.x = 0; | |
mask.y = 0; | |
mask.width = this.actualWidth; | |
mask.height = this.actualHeight; | |
} | |
else | |
{ | |
mask = new Quad(1, 1, 0xff00ff); | |
//the initial dimensions cannot be 0 or there's a runtime error, | |
//and these values might be 0 | |
mask.width = this.actualWidth; | |
mask.height = this.actualHeight; | |
this.image.mask = mask; | |
this.addChild(mask); | |
} | |
} | |
else | |
{ | |
mask = this.image.mask as Quad; | |
if(mask !== null) | |
{ | |
mask.removeFromParent(true); | |
this.image.mask = null; | |
} | |
} | |
} | |
override protected function refreshCurrentTexture():void | |
{ | |
super.refreshCurrentTexture(); | |
calculateTextureScaleMultipliers(); | |
} | |
override protected function cleanupTexture():void | |
{ | |
super.cleanupTexture(); | |
calculateTextureScaleMultipliers(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment