10

I want to call the zoom in and zoom out function of context menu from custom button In adobe flex application.

Code something like this :

onZoomInButtonClick()
{
this.contextMenu.customItems.zoom.doIn();
}
ketan
  • 19,129
  • 42
  • 60
  • 98
AsadYarKhan
  • 678
  • 2
  • 14
  • 31

3 Answers3

7

There is (at least to my knowledge) no way for you to access the flash player zoom in/out commands via code.

You can fake it though by doing the following in your document class (top-most display object under stage)

stage.addEventListener(MouseEvent.MOUSE_WHEEL,mouseWheel,true,2); //listen on the capture phase of the event and give a higher priority than default so it reacts before your grid

function mouseWheel(e:MouseEvent):void {
    if(!e.ctrlKey) return; //Ctrl has to be pressed or we ignore the wheel

    e.stopImmediatePropagation(); //this stops the event from firing on anything else, like your data grid

    var tmpScale:Number = scaleX + (e.delta > 0 ? .2 : -.2); //lets zoom in/out in incriments of 20% (.1)

    if(tmpScale < 1){ //if the scale is less than one now, lets keep it at 1
        tmpScale = 1;
        this.scaleX = 1;
        this.x = 0;
        this.scaleY = 1;
        this.y = 0;
        return;
    }

    if(tmpScale > 4){ //lets set the max to 4
        tmpScale = 4;
    }

    scaleAroundMouse(this,tmpScale);

}

function scaleAroundMouse(objectToScale:DisplayObject, scaleAmount:Number, bounds:Rectangle = null):void {
    // scaling will be done relatively
    var relScaleX:Number = scaleAmount / objectToScale.scaleX;
    var relScaleY:Number = scaleAmount / objectToScale.scaleY;
    // map vector to centre point within parent scope

    var scalePoint:Point = objectToScale.localToGlobal( new Point(objectToScale.mouseX, objectToScale.mouseY));
    scalePoint = objectToScale.parent.globalToLocal( scalePoint );
    // current registered postion AB
    var AB:Point = new Point( objectToScale.x, objectToScale.y );
    // CB = AB - scalePoint, objectToScale vector that will scale as it runs from the centre
    var CB:Point = AB.subtract( scalePoint );
    CB.x *= relScaleX;
    CB.y *= relScaleY;
    // recaulate AB, objectToScale will be the adjusted position for the clip
    AB = scalePoint.add( CB );
    // set actual properties

    if(bounds){
     var limits:Rectangle = new Rectangle(
        bounds.x + (bounds.width - (objectToScale.width * relScaleX)),
        bounds.y + (bounds.height - (objectToScale.height * relScaleY)),
        (objectToScale.width * relScaleX) - bounds.width,
        (objectToScale.height * relScaleY) - bounds.height
     );

     if(AB.x < limits.x) AB.x = limits.x;
     if(AB.x > limits.x + limits.width) AB.x = limits.x + limits.width;
     if(AB.y < limits.y) AB.y = limits.y;
     if(AB.y > limits.y + limits.height) AB.y = limits.y + limits.height;       
    }

    objectToScale.scaleX = scaleAmount;
    objectToScale.scaleY = scaleAmount;
    objectToScale.x = AB.x;
    objectToScale.y = AB.y;
}
BadFeelingAboutThis
  • 14,445
  • 2
  • 33
  • 40
  • Thanks your code is almost working but If these things resolve it will be mark as answer and bounty is urs.: – AsadYarKhan Mar 28 '13 at 05:52
  • please how to disable the grid scroll when ctrl is press , when i press control and scroll on grid it start to scroll vertically rather then zoom. – AsadYarKhan Mar 28 '13 at 05:53
  • Second is that when i provide this(application object it zoom full 4 scale) but when i provide grid object then it does not zoom only once means only one time it scale the object, i keep scrolling afterward it do not zoom more at all.. ???why – AsadYarKhan Mar 28 '13 at 05:55
  • I tried to change tmpScale = 4; to 8 or even higher but it still does not do that?? – AsadYarKhan Mar 28 '13 at 06:13
  • 1
    I updated the code to address your first request above. You're second comment I'm having a little trouble understanding? Might have to do with how the Flash IDE doesn't dispatch mouse wheel events properly. see this: http://stackoverflow.com/questions/6240469/does-mouse-wheel-have-a-min-delta-value-before-it-fires/12570330#12570330 – BadFeelingAboutThis Mar 28 '13 at 15:54
  • Zoom using default feature(right click slect zoom in):http://imageshack.us/photo/my-images/402/grid2t.png/ – AsadYarKhan Mar 29 '13 at 06:10
  • Using ur code The grid cloumns shrink,if u focus on grid the whole grid is shrinking if some how we can manage that ,The whole grid do not shrink and maintain its original size or inscrase on zoom then horizontal scroll bar is appear as well so we can scroll to see the zooming grid hidden area at this zoom level than it will be close to real effect,and I tried to do that but cant can u please do that ? :( – AsadYarKhan Mar 29 '13 at 06:10
  • 1
    Are you using the standard DataGrid component? `spark.components.dataGrid`? Looks like it has some weird code in it that takes into consideration it's global scale. You may be able to write a custom `itemRenderer` for the component that may help. – BadFeelingAboutThis Mar 29 '13 at 15:43
  • I am using mx.Controls.AdvanceDataGrid.You try ur code in this grid urslef and see the outcome ,I am using flex3 spark api available is in flex4. – AsadYarKhan Apr 02 '13 at 05:07
  • I did tried in mx.controls.DataGrid but not working there as well same behaviour as mx.Controls.AdvanceDataGrid. and i check spark namespace in my api it doesnot have,I think it is introduce in action script 4 or flex 4. – AsadYarKhan Apr 02 '13 at 05:34
  • At least you did effort that's why I am giving u bounty :) – AsadYarKhan Apr 03 '13 at 09:54
  • 1
    @AsadYarKhan - thanks. I'm not sure if the spark data grid would behave any differently. I actually don't use the flex components at all, but I know that many of them try to be 'smart' when you scale them. If you're very determined you could write your own or try a third party one. – BadFeelingAboutThis Apr 03 '13 at 16:55
  • Actually now a days i m working on other task thats why i didn't focusly worked on it,but I ll try as u said when i comeback to it. – AsadYarKhan Apr 04 '13 at 05:24
3

Ok, advancedatagrid may listen keyboard events, when ctrl key down - listen mousewheel events and change scale, see example:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
        <fx:Script>
            <![CDATA[

                protected function doMouseWheel(evt:MouseEvent):void 
                {
                    scaleX = scaleY += evt.delta * 0.1;
                }

                protected function adg_keyDownHandler(event:KeyboardEvent):void
                {
                    if (event.ctrlKey)
                    {
                        systemManager.addEventListener(MouseEvent.MOUSE_WHEEL, doMouseWheel);
                    }
                }

                protected function adg_keyUpHandler(event:KeyboardEvent):void
                {
                    if (!event.ctrlKey)
                    {
                        systemManager.removeEventListener(MouseEvent.MOUSE_WHEEL, doMouseWheel);
                    }
                }

            ]]>
        </fx:Script>    

        <mx:AdvancedDataGrid id="adg" keyDown="adg_keyDownHandler(event)" keyUp="adg_keyUpHandler(event)"
                             horizontalCenter="0" verticalCenter="0">
            <mx:columns>
                <mx:AdvancedDataGridColumn dataField="@label"/>
                <mx:AdvancedDataGridColumn dataField="@data" />
            </mx:columns>
            <mx:dataProvider>
                <s:XMLListCollection id="dp">
                    <s:source>
                        <fx:XMLList>
                            <product label="Product 1" data="3" />
                            <product label="Product 2" data="1" />
                            <product label="Product 3" data="4" />
                            <product label="Product 4" data="1" />
                            <product label="Product 5" data="5" />
                            <product label="Product 6" data="9" />
                        </fx:XMLList>
                    </s:source>
                </s:XMLListCollection>
            </mx:dataProvider>
        </mx:AdvancedDataGrid>

    </s:Application>
Ilya Zaytsev
  • 1,055
  • 1
  • 8
  • 12
2

In order to zoom in/out a vector graphics, you plainly change its scaleX and scaleY properties uniformly. The vector renderer of Flash will draw you a correct picture. In order to zoom in on a Bitmap and not get pixelated output, you have to convert it into a vector graphics object like this:

var sh:Shape=new Shape();
sh.graphics.beginBitmapFill(yourBitmap);
sh.graphics.lineStyle(0,0,0); // to not have border lines
sh.graphics.drawRect(0,0,yourBitmap.width,yourBitmap.height);
sh.graphics.endFill();

And then adjusting scaleX and scaleY of that shape will produce interpolated output as you seemingly want.

Vesper
  • 18,599
  • 6
  • 39
  • 61
  • My object is advanceDatagrid or Grid.I want to zoom grid not bitmap :) – AsadYarKhan Mar 27 '13 at 07:39
  • You have to go down to primitives. Also, check if your data grid's `cacheAsBitmap` is false. – Vesper Mar 27 '13 at 07:40
  • what please explain go down to primitice ?? – AsadYarKhan Mar 27 '13 at 07:44
  • 1
    I've quickly looked up if you can dig what's used in Flex to dislpay anything, and failed to find any means of tearing up the engine, thus you cannot "go down to primitives", sadly. But, you can control `cacheHeuristic` property of your `AdvancedDataGrid` object, setting it to false might force Flex to allow Flash graphics renderer to interpolate data grid image as you require. But, check the [manual](http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/core/UIComponent.html#cacheHeuristic) first, regarding this and `cachePolicy` properties. Perhaps setting both to off will do – Vesper Mar 27 '13 at 08:03