"...use the initial aspect ratio to calculate the other dimension and set it.."
This actually worked!
I used the resizing boolean and maintainAspectRatio property to conditionally
set the aspect ratio, then in mouseMove, check for an aspectRatio and calculate
and set the other dimension. It is properly handling both maintainAspectRatio
values.
Thanks again, Alex.
Tracy
Here is the current code in case anyone wants to see the details.
package MIPComponents
{
import mx.controls.Image;
import flash.events.Event;
import flash.events.MouseEvent;
import mx.controls.Button
import flash.geom.Point;
import flash.display.GradientType;
public class CloseResizeImage extends Image
{
private var _iImageRightX:int;
private var _iImageBottomY:int;
private var _bIsResizing:Boolean = false;
private var _iAspectRatio:Number = 0;
private var _btnModify:Button;
private var _imgResizeHandle:Image;
[Embed(source="../assets/return.gif")]
private var resizerSkin:Class;
override public function load(url:Object = null):void
{
super.load(url);
if (!_btnModify)
{
_btnModify = new Button;
_btnModify.width = 22;
_btnModify.height = 22;
_btnModify.addEventListener(MouseEvent.CLICK, showPropertyEditor);
_btnModify.x = this.width + 2;
_btnModify.y = 1;
_btnModify.label = "...";
_btnModify.toolTip = "Edit control properties";
_btnModify.styleName = "MIPButton";
addChildAt(_btnModify, 1);
//Add the resize handle
_imgResizeHandle = new Image;
_imgResizeHandle.source = resizerSkin;
_imgResizeHandle.toolTip = "Drag to resize";
_imgResizeHandle.buttonMode = true;
addChildAt(_imgResizeHandle, 2);
_imgResizeHandle.addEventListener("mouseDown", onMouseDownResize);
}
setChildIndex(_btnModify, 1);
setChildIndex(_imgResizeHandle, 2);
}//
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
_btnModify.move(unscaledWidth - _btnModify.getExplicitOrMeasuredWidth(),
0);
_btnModify.setActualSize(_btnModify.getExplicitOrMeasuredWidth(),
_btnModify.getExplicitOrMeasuredHeight());
var resizerWidth:Number = _imgResizeHandle.getExplicitOrMeasuredWidth();
var resizerHeight:Number = _imgResizeHandle.getExplicitOrMeasuredHeight();
_imgResizeHandle.move(unscaledWidth - resizerWidth, unscaledHeight -
resizerHeight);
_imgResizeHandle.setActualSize(resizerWidth, resizerHeight);
// Draw a simple border around the child components.
this.graphics.clear();
graphics.lineStyle(1, 0x000000, 1.0);
graphics.drawRect(-2, -2, unscaledWidth+4, unscaledHeight+4); //draw the
outside black border
graphics.lineStyle(1, 0xffff00, 1.0);
graphics.drawRect(-1, -1, unscaledWidth+2, unscaledHeight+2); //draw the
inside yellow border
if (!_bIsResizing) {
if (this.maintainAspectRatio == true) {
_iAspectRatio = (unscaledWidth / unscaledHeight);
}
}
}//updateDisplayList
private function showPropertyEditor(oEvent:Event):void
{
}
private function onMouseDownResize(oEvent:Event):void
{
_bIsResizing = true;
stage.addEventListener("mouseUp", onMouseUpResize);
stage.addEventListener("mouseLeave", onMouseUpResize);
stage.addEventListener("mouseMove", onMouseMoveResize);
}
private function onMouseUpResize(oEvent:Event):void
{
_bIsResizing = false;
stage.removeEventListener("mouseUp", onMouseUpResize);
stage.removeEventListener("mouseLeave", onMouseUpResize);
stage.removeEventListener("mouseMove", onMouseMoveResize);
}
private function onMouseMoveResize(oEvent:MouseEvent):void
{
var ptStage:Point = new Point(oEvent.stageX, oEvent.stageY); //mouse
Point in global coord space
var ptLocal:Point = parent.globalToLocal(ptStage); //mouse pt in
component space
var iWidth:int;
var iHeight:int;
if (ptLocal.x >= x) { //make sure we
don't go less than zero
iWidth = ptLocal.x - x;
if (this.explicitWidth != iWidth) { //only set if
different
this.explicitWidth = iWidth; //set the width
if (_iAspectRatio > 0) {
this.explicitHeight = (iWidth / _iAspectRatio); //calc and set the
height
}
}
}//if (ptLocal.x >= x)
if (ptLocal.y >= y) { //do the same for
height
iHeight = ptLocal.y - y;
if (this.explicitHeight != iHeight) {
this.explicitHeight = iHeight;
if (_iAspectRatio > 0) {
this.explicitWidth = (iHeight * _iAspectRatio);
}
}
}//if (ptLocal.y >= y)
}
public function CloseResizeImage()
{
super();
}
}//class
}//package
________________________________________
From: [email protected] [mailto:[EMAIL PROTECTED] On Behalf Of
Tracy Spratt
Sent: Monday, April 16, 2007 7:05 PM
To: [email protected]
Subject: RE: [flexcomponents] Extend Image, add button, resize handle. Sound
familiar Alex? Follow-up question
Hmm, "updateDisplayList call when resizing is false..." only happens during the
initialization processing, if I have implemented your suggestion correctly.
I am thinking that, when either the width or height is set, that I need to use
the initial aspect ratio to calculate the other dimension and set it.
Something like that. Or is there a way for me to "read" the content image's
actual dimensions?
Tracy
________________________________________
From: [email protected] [mailto:[EMAIL PROTECTED] On Behalf Of
Alex Harui
Sent: Monday, April 16, 2007 5:25 PM
To: [email protected]
Subject: RE: [flexcomponents] Extend Image, add button, resize handle. Sound
familiar Alex? Follow-up question
I would add a resizing boolean which is set to true on mouseDown and false on
mouseUp.
If there is an updateDisplayList call when resizing is false, I'd save the
width/height as the "max".
Then in mouseMove, I would limit the width/height to the max values.
________________________________________
From: [email protected] [mailto:[EMAIL PROTECTED] On Behalf Of
Tracy Spratt
Sent: Monday, April 16, 2007 2:13 PM
To: [email protected]
Subject: [flexcomponents] Extend Image, add button, resize handle. Sound
familiar Alex? Follow-up question
I am extending a few controls to provide an "edit" mode that shows a border,
resize handle and a button to pop-up a property editor.
I am experimenting with some code for a "CloseResizeImage" prototype component
Alex Harui posted on flexcoders, that seems to work much better than the canvas
overlay method I was attempting before (especially in autoLayout containers!).
It is working pretty well, except that for an image with a fixed aspect ratio,
the resize handle (and therefore my border) can be moved beyound the right and
bottom of the image.
I am looking for suggestions on how to constrain the resizer drag to stay
within the image border. I will be busy hacking at mouseMoveHandler in the
code below, but any pointers will be appreciated.
Tracy Spratt
public class CloseResizeImage extends Image
{
public function CloseResizeImage()
{
super();
}
private var closeButton:Button;
private var resizer:Image;
[Embed(source="ATOC_F8_v3r9_8.swf",symbol="Button_Up")]
private var upSkin:Class;
[Embed(source="ATOC_F8_v3r9_8.swf",symbol="Button_Over")]
private var overSkin:Class;
[Embed(source="ATOC_F8_v3r9_8.swf",symbol="Button_Down")]
private var downSkin:Class;
[Embed(source="ATOC_F8_v3r9_8.swf",symbol="WindowResizer")]
private var resizerSkin:Class;
override public function load(url:Object = null):void
{
super.load(url);
if (!closeButton)
{
closeButton = new Button;
closeButton.setStyle("upSkin", upSkin);
closeButton.setStyle("overSkin", overSkin);
closeButton.setStyle("downSkin", downSkin);
addChildAt(closeButton, 1);
closeButton.addEventListener("click", clickHandler);
resizer = new Image;
resizer.source = resizerSkin;
addChildAt(resizer, 2);
resizer.addEventListener("mouseDown", mouseDownHandler);
}
setChildIndex(closeButton, 1);
setChildIndex(resizer, 2);
}
override protected function updateDisplayList(uw:Number, uh:Number):void
{
super.updateDisplayList(uw, uh);
closeButton.move(uw - closeButton.getExplicitOrMeasuredWidth(), 0);
closeButton.setActualSize(closeButton.getExplicitOrMeasuredWidth(),
closeButton.getExplicitOrMeasuredHeight());
var rw:Number = resizer.getExplicitOrMeasuredWidth();
var rh:Number = resizer.getExplicitOrMeasuredHeight();
resizer.move(uw - rw, uh - rh);
resizer.setActualSize(rw, rh);
// graphic is porous so make a hit area for it.
resizer.graphics.clear();
resizer.graphics.beginFill(0, 0);
resizer.graphics.moveTo(rw, 0);
resizer.graphics.lineTo(0, rh);
resizer.graphics.lineTo(rw, rh);
resizer.graphics.lineTo(rw, 0);
resizer.graphics.endFill();
}
private function clickHandler(event:Event):void
{
visible = false;
}
private function mouseDownHandler(event:Event):void
{
stage.addEventListener("mouseUp", mouseUpHandler);
stage.addEventListener("mouseLeave", mouseUpHandler);
stage.addEventListener("mouseMove", mouseMoveHandler);
}
private function mouseUpHandler(event:Event):void
{
stage.removeEventListener("mouseUp", mouseUpHandler);
stage.removeEventListener("mouseLeave", mouseUpHandler);
stage.removeEventListener("mouseMove", mouseMoveHandler);
}
private function mouseMoveHandler(event:MouseEvent):void
{
var stagePt:Point = new Point(event.stageX, event.stageY);
var localPt:Point = parent.globalToLocal(stagePt);
if (localPt.x >= x)
explicitWidth = localPt.x - x;
if (localPt.y >= y)
explicitHeight = localPt.y - y;
}