原著:Robert Wingate
翻译:alphachi
如果不是一个Director新手,就肯定听说过Imaging Lingo。使用这套随Director 8.0添加的全新Lingo命令,能够对影片中图形进行像素级控制,例如运行时创建、填充与合成图像。虽然使用CastEffects、DrawXtra或Composite Xtras也可以达到同样的效果,但由于Imaging Lingo是Director本身内置的功能,所以在许多方面拥有不可比拟的优势。
本文主要演示了一项在Mui对话框的callback处理程序中使用Imaging Lingo的技巧。你将学会如何根据对话框的设置即时将几个图形元素合为一个,然后利用Mui Xtra的ItemUpdate在运行时更新对话框中的图形。关于如何使用Mui Xtra创建对话框,参考这里。
首先操作一下样本影片,注意复选框或单选按钮被点击后图形的变化,并确保在演员表里有多个图形供合成使用。实际上,通过将下面看到的六个单独的图形元素添加到一个空的面板图形上,这个对话框能够产生128种可能的合成效果。
这个程序里使用了七个演员
这便是Imaging Lingo的强大之处——运行时合成图像。下面让我们看看具体是怎么做的。
一、在屏幕上获取对话框
首先使用Mui Xtra根据下面的步骤建立一个对话框:
1) 创建一个此Xtra的实例
2) 配置对话框的整体属性
3) 配置每个元素的局部属性
4) 显示对话框
1. 什么是Mui Callback处理程序
Mui callback处理程序类似一个自编处理程序,只是无法从代码中直接调用。但只需传递callback处理程序的名称,Mui便会对其进行适时的调用。
当需要Mui Xtra显示对话框时,它便准备将事件传递给callback处理程序,两者专门设计用来处理对话框中发生的用户交互。也就是说,无论何时用户输入了文本,拖动了滑块,点击了复选框或者以其他任何方式同对话框发生了交互,此Xtra都会如实告诉处理程序发生了什么,而处理程序则以相应的方式作出响应。callback处理程序和对话框息息相关,两者互相协作,合成并更新图像。
当对话框处于可见状态时,此Xtra会注意每一个用户交互,并将三部分数据发送到callback处理程序:
1) 用户事件的类型(一个符号型数据)
2) 在#windowItemList中的窗口组件位置(一个整型数据)
3) 窗口组件当前的属性(一个属性列表)
这个callback处理程序主要由case语句构成,以便区分不同的用户交互,检查项目属性以确定当前的窗口组件,最后决定对当前的窗口组件作出怎样的改变。为了说明如何使用callback处理程序筛选用户事件,请看下面的例子:
on MyDialogCallback (event, eventData, itemPropList)
case (event) of
#itemChanged:
-- 用户已经使对话框作了一些改变,使用itemPropList.type检查具体的改变情况
put itemPropList
#itemclicked:
-- 用户在对话框中点击了一个按钮,使用itemPropList.type寻找这个按钮
put itemPropList
end case
end
与在Message窗口中输入当前窗口组件属性相比,上面的代码不会有更大的用途,但它演示了itemPropList的使用。样本影片中的itemPropList会被发送到MyDialogCallback处理程序,因为当你点击了“Show Title”复选框后,将会产生下面的列表:
-- [#value:1, #type:#checkBox, #attributes:[], #title:"Show Title", #tip:"tip", #locH:5, #locV:56, #width:132, #height:12, #enabled:1]
从上表中能够很容易的确定:
1) 用户点击了一个复选框(#type属性)
2) 这个复选框是“Show Title”(#title属性)
3) 这个复选框新的状态是“已选中”(#value属性)
2. 使用callback处理程序
现在已经确定发生了何种交互(用户选中了复选框“Show Title”),下面来看看MyDialogCallback处理程序是如何响应的。
global lsWidgetStates
on MyDialogCallback (event, eventData, itemPropList)
case (event) of
#itemChanged:
case (itemPropList.type) of
#checkBox:
-- 用户点击了一个复选框,通过itemPropList.title来判断具体是哪一个
case (itemPropList.title) of
"Show Title" : lsWidgetStates.title = itemPropList.value
"Show Author": lsWidgetStates.author = itemPropList.value
end case
end case
end case
end
其中名为lsWidgetStates的全局列表用来存储每个窗口组件的当前取值,根据这些值决定怎样合成图形。这个列表看起来像这样:
lsWidgetStates = [#publisher: 0, #title: 0, #description: 0, #author: 0, #pageCurl: 0, #graphic: 0, #color: "White Background"]
下图显示了复选框被点击后究竟发生了什么:
注意callback处理程序的执行过程
每次点击了复选框或单选按钮后,MyDialogCallback都会调用UpdateDialogImage处理程序,利用lsWidgetStates确定哪些图形元素需要被合成到最终显示的图形上。
UpdateDialogImage的作用在于:
1) 建一个新的空白面板图像
2) 根据lsWidgetStates的取值给背景上色
3) 根据lsWidgetStates的取值合成复选框选中的图形
4) 使用Mui的ItemUpdate将合成后的图像发送给对话框
原著:Robert Wingate
翻译:alphachi
二、输入Imaging Lingo
这个程序只需要使用一点Imaging Lingo的知识,因为copyPixels一个函数几乎就可以完成所有的工作。这个函数将一个图像中指定区域的像素复制到另一个图像的指定区域,其中的“区域”既可以是一个rect,也可以是一个quad,此外还可以给复制的像素使用颜色、油墨、混色、抖动和遮罩。copyPixels的语法如下:
destinationImage.copyPixels (sourceImage, destinationRect, sourceRect {paramList})
让我们来看看UpdateDialogImage是如何使用copyPixels创建空白面板图像的:
on UpdateDialogImage ()
w = member ("BlankSlate").width
h = member ("BlankSlate").height
r = member ("BlankSlate").rect
-- 1. 在内存中创建一个图像,然后将空白面板演员的图像复制进去
newImage = image (w, h, 16)
newImage.copyPixels (member("BlankSlate").image, r, r)
接着,UpdateDialogImage根据目前单选按钮的状态进行上色:
-- 2. 使用单选按钮指定的的颜色填充newImage
rFillArea = r
if (lsWidgetStates.color = "White Background") then
newImage.fill (rFillArea, rgb( 255,255,255)) -- white
else
newImage.fill (rFillArea, rgb( 180,220,240 )) -- light blue
end if
如果复选框被选中,则添加相应的图形:
-- 3. 根据复选框的当前状态添加相应的元素
if lsWidgetStates.publisher then -- Publisher
CompositeElement( newImage, member ("publisher"), 9, 6 )
end if
if lsWidgetStates.title then -- Title
CompositeElement( newImage, member ("bookTitle"), 9, 50 )
end if
CompositeElement处理程序首先计算出destRect的值,然后将这些像素置于相应的位置。
on CompositeElement (imgPtr, mElement, nLft, nTop)
sourceImage = mElement.image
destRect = rect (nLft, nTop, nLeft+mElement.width, nTop+mElement.height)
imgPtr.copyPixels (sourceImage, destRect,sourceImage.rect, [#ink:1])
end
还要注意,和别的对象一样,Lingo通过指针引用图像对象。这意味着如果将一个图像对象作为参数传递给一个函数的话,此函数能够更改这个对象本身,以代替此对象的一个复本。UpdateDialogImage通过指针将这个图像对象传递给了CompositeElement,让其对原始的图像对象进行相应的调整。
最后,一旦我们完成了图像的合成,还需要将其覆盖存储到对话框使用的位图演员处:
-- 4. 现在更新位图演员
member ("dialogGraphic").image = newImage
到此为止,我们已经看到了MyDialogCallback是如何判定鼠标在复选框中的点击并保存其状态的,也已经看到了UpdateDialogImage是如何创建一个新的图形并为每个状态为“TRUE”窗口组件调用CompositeElement的。剩下的唯一一步就是在对话框中显示新的图形。
三、更新对话框图形
像updateState一样,Mui Dialog Xtra的ItemUpdte命令根据用户交互更新窗口组件,唯一的区别在于它只能处理Mui对话框中窗口组件的变化。幸运的是,Mui Dialog Xtra认为图形也是窗口组件,这意味着能够在对话框运行时对其进行更新。
UpdateDialogImage首先调用ItemUpdate命令,此命令的语法如下:
dialogObject.ItemUpdate (intItemNumber, itemInputPropList)
ItemUpdate使用属性列表记录需要更新的元素。由于这个图形是用来定义对话框的线性列表中的第18个元素,因此只需先复制并根据指定的名称就可将其传递给ItemUpdate:
-- 5. 在对话框中显示合成后的图像
lsNewGraphicWidget = lsDialog[18].duplicate()
lsNewGraphicWidget.value = member ("dialogGraphic")
oDialog.ItemUpdate (18, lsNewGraphicWidget)
四、用途
大多数应用程序向导和许多打印选项对话框都需要根据对话框的当前设置更新显示内容,而通过与Mui Dialog Xtra一起使用Imaging Lingo,便能够达到这个目的。现在这项技巧已经被广泛用于各种商业程序中。
|