Calling the zoom in and out of context menu from custom button in flex3
Asked Answered
H

3

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();
}
Hexone answered 1/3, 2013 at 11:56 Comment(2)
Nice question. I think native solution impossible.Flunky
Is there any other way to do zooming. I want to do zooming in advancedatagrid using ctrl+mousewheel.Hexone
S
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;
}
Syst answered 27/3, 2013 at 22:20 Comment(13)
Thanks your code is almost working but If these things resolve it will be mark as answer and bounty is urs.:Hexone
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.Hexone
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.. ???whyHexone
I tried to change tmpScale = 4; to 8 or even higher but it still does not do that??Hexone
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: #6240969Syst
Zoom using default feature(right click slect zoom in):imageshack.us/photo/my-images/402/grid2t.pngHexone
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 ? :(Hexone
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.Syst
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.Hexone
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.Hexone
At least you did effort that's why I am giving u bounty :)Hexone
@Hexone - 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.Syst
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.Hexone
F
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>
Flunky answered 4/3, 2013 at 8:9 Comment(3)
scaling is not producing the quality result.I want zooming feature.Hexone
do you think there are differences?Flunky
yes in scaling u increase the width and height of object but in zooming we play with canvas, see this superuser.com/questions/153998/…Hexone
T
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.

Twenty answered 27/3, 2013 at 7:35 Comment(4)
My object is advanceDatagrid or Grid.I want to zoom grid not bitmap :)Hexone
You have to go down to primitives. Also, check if your data grid's cacheAsBitmap is false.Twenty
what please explain go down to primitice ??Hexone
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 first, regarding this and cachePolicy properties. Perhaps setting both to off will doTwenty

© 2022 - 2024 — McMap. All rights reserved.