从flex3中的自定义按钮调用放大和缩小上下文菜单
Posted
技术标签:
【中文标题】从flex3中的自定义按钮调用放大和缩小上下文菜单【英文标题】:Calling the zoom in and out of context menu from custom button in flex3 【发布时间】:2013-02-15 22:08:17 【问题描述】:我想在 adobe flex 应用程序中从自定义按钮调用上下文菜单的放大和缩小功能。
代码如下:
onZoomInButtonClick()
this.contextMenu.customItems.zoom.doIn();
【问题讨论】:
好问题。我认为本地解决方案是不可能的。 有没有其他方法可以进行缩放。我想使用 ctrl+鼠标滚轮放大高级数据网格。 【参考方案1】:好的,advancedatagrid 可能会监听键盘事件,当 ctrl 键按下时 - 监听鼠标滚轮事件并更改比例,请参见示例:
<?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>
【讨论】:
缩放没有产生高质量的结果。我想要缩放功能。 你觉得有区别吗? 是的,在缩放时你会增加对象的宽度和高度,但在缩放时我们会使用画布,请参阅superuser.com/questions/153998/…【参考方案2】:为了放大/缩小矢量图形,您可以简单地统一更改其scaleX
和scaleY
属性。 Flash 的矢量渲染器会为您绘制正确的图片。为了放大位图而不是像素化输出,您必须将其转换为矢量图形对象,如下所示:
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();
然后调整该形状的scaleX
和scaleY
将产生您看似想要的插值输出。
【讨论】:
我的对象是 AdvanceDatagrid 或 Grid。我想缩放网格而不是位图 :) 你必须深入到原语。另外,检查您的数据网格的cacheAsBitmap
是否为假。
请解释什么??
我很快就查找了你是否可以挖掘 Flex 中使用的东西来显示任何东西,但没有找到任何破坏引擎的方法,因此很遗憾,你不能“归结为原语”。但是,您可以控制 AdvancedDataGrid
对象的 cacheHeuristic
属性,将其设置为 false 可能会强制 Flex 允许 Flash 图形渲染器根据需要插入数据网格图像。但是,首先检查manual,关于这个和cachePolicy
属性。也许将两者都关闭就可以了【参考方案3】:
(至少据我所知)您无法通过代码访问 Flash 播放器的放大/缩小命令。
您可以通过在文档类中执行以下操作来伪造它(舞台下最顶部的显示对象)
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;
【讨论】:
感谢您的代码几乎可以工作,但如果这些问题解决了,它将被标记为答案,赏金是我们的。: 请问如何在按下 ctrl 时禁用网格滚动,当我按下 control 并在网格上滚动时,它开始垂直滚动而不是缩放。 我更新了代码以解决您上面的第一个请求。你是第二条评论,我有点理解困难?可能与 Flash IDE 无法正确分派鼠标滚轮事件有关。看到这个:***.com/questions/6240469/… 您使用的是标准的DataGrid 组件吗?spark.components.dataGrid
?看起来它有一些奇怪的代码,考虑到它的全球规模。您也许可以为可能有帮助的组件编写自定义 itemRenderer
。
@AsadYarKhan - 谢谢。我不确定火花数据网格的行为是否会有所不同。实际上我根本不使用 flex 组件,但我知道当你缩放它们时,它们中的许多都试图变得“聪明”。如果您非常确定,您可以自己编写或尝试第三方。以上是关于从flex3中的自定义按钮调用放大和缩小上下文菜单的主要内容,如果未能解决你的问题,请参考以下文章
带有旋转,放大,缩小和移动在android中的自定义textview?