一、概述
Wow插件采用xml文件来描述UI布局,其基本格式如下:
<!-- Ui标签是包含所有其他标签的根标签 --> <Ui xmlns="http://www.blizzard.com/wow/ui/" <!--固定写法--> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/...InterfaceFrameXMLUI.xsd"> <Script file="localization.lua"/> <!-- 在此载入用于汉化的lua文件 --> <Frame name="zBar(名称)" parent="UIParent(父标签)" inherits="myFather(继承)" toplevel="true(等级)" movable="true(可移动)" enableMouse="true(允许鼠标事件)" frameStrata="HIGH(层级)" hidden="false(是否隐藏)"> <!-- 一个Frame框架 --> <!-- 大小 --> <Size> <AbsDimension x="100" y="100"/><!-- 绝对尺寸--> </Size> <Size x="100" y="100"/><!--简化写法--> <!--锚点,用来标记相对位置,可以有多个--> <Anchors> <Anchor Point="LEFT(本控件参考点)" relativeTo="xBar(参考控件)" relativePoint="LEFT(参考控件的参考点)"> <Offset> <!--偏移值--> <AbsDimension x="10" y="10"/> </Offset> <Offset x="10" y="10"/><!--简化写法--> </Anchor> </Anchors> <!--背景和边框--> <Backdrop name="$parentBackdrop" edgeFile="InterfaceDialogFrameUI-DialogBox-Border(边框贴图)" bgFile="InterfaceDialogFrameUI-DialogBox-Background(背景贴图)" tile="true"> <EdgeSize> <AbsValue val="18"/> <!--边框缩放大小--> </EdgeSize> <TileSize> <AbsValue val="16"/> </TileSize> <BackgroundInsets> <AbsInset left="5" right="5" top="5" bottom="5"/><!--背景四周留白--> </BackgroundInsets> </Backdrop> <!--分层,主要放置贴图材质和字符--> <Layers> <Layer level="BACKGROUND"> <!--背景层--> <Texture name="$parentRed" file="(贴图)" hidden="true"/> </Layer> <Layer level="ARTWORK"> <!--艺术层--> <FontString name="$parent(名字)" inherits="Font" justifyH="CENTER"/> </Layer> <Layer level="OVERLAY"> <!--覆盖层--> <Texture name="$parentShine" file="(贴图)" alphaMode="ADD(透明模式)" hidden="true"/> <Anchors> <Anchor point="CENTER"/> <Anchors> </Texture> </Layer> <Layers> <!--嵌入其他框架--> <Frames> </Frames> <!-- 脚本部分,用于处理事件 --> <Scripts> <OnLoad>处理载入事件</OnLoad> <OnEvent>处理用RegisterEvent注册过的事件</OnEvent> <OnUpdate>更新事件</OnUpdate> <OnClick>点击事件</OnClick> <OnDoubleClick>双击事件</OnDoubleClick> <OnEnter>鼠标进入</OnEnter> <OnLeave>鼠标移除</OnLeave> <OnDragStart>self:StartMoving()开始拖放</OnDragStart>
<OnDragStop>self:StopMovingOrSizing()停止拖放</OnDragStop> <OnReceiveDrag>接受拖放</OnReceiveDrag> <OnValueChanged>值改变(用于Slider滑块)</OnValueChanged> </Scripts> </Frame> </Ui>
下面开始逐个解释:
(1)UIParent
UIParent是由游戏创建的,作为所有其他Frame的父view。我们定义的Frame也应该是UIParent的子view,否则当按下Alt+Z或者整体UI缩放时,我们的Frame将不会生效。
另外parent和inherits属性是有区别的:
- parent 是父控件,表示依存关系,如果父控件隐藏,子控件也会隐藏
- inherits 是继承关系,表示本控件未声明的属性全部继承自某控件(包括事件处理脚本)
(2)Anchor(锚点)
Anchor表示依附关系,描述了本控件与其他控件的相对位置。一个控件有八个固有锚点:
一个控件可以有多个锚点,控件会按照每个锚点对齐。比如,LEFT和RIGHT两个锚点分别对齐另一个控件的LEFT和RIGHT,它的宽度会被拉伸到对齐控件的宽度。
(3)Size(尺寸)
无论是尺寸(Size)还是偏移量(Offset),我们都可以选择使用绝对值(AbsDimension)或相对值(RelDimension),其中:
- 相对值是以屏幕宽高的比例来计算的,其数值为(0~1),比如宽高均是AbsDimension=0.5的控件将占据四分之一屏幕;
- 绝对值是以像素来计算的,但需要除以缩放比例(scale setting),因为Wow的屏幕高度总是被定义为768像素,如果你的屏幕高度是1024,那缩放比例就是0.75,比如你的控件高度定义为RelDimension=786,它将占据整个屏幕高度;宽度则是以宽高比来计算的。
(4)Backdrop(背景)
- Backdrop包含背景和边框,其中:
- bgFile 背景贴图
- tile 是否平铺
- edgeFile 边框贴图
- TileSize 边框部分所占材质贴图的宽度
- EdgeSize 拐角部分所占材质贴图的宽度
- BackgroundInsets 背景内留白
其中边框和拐角贴图都包含在edgeFile中,边框是四条直线,拐角则是四个角。
(5)Strata(层级)
Frame的层级(Strata)决定了它的显示顺序,层级越高显示越靠前,从高到低分为如下层级:
- TOOLTIP
- FULLSCREEN_DIALOG
- FULLSCREEN
- DIALOG
- HIGH
- MEDIUM
- LOW
- BACKGROUND
(6)Layer(层)
一个层可以包含材质(Texture)或者文本(FontString),比如一个Frame的标题就可以用一个Layer来表示。
Layer也有层级之分,决定了显示顺序,从高到低分为:
- HIGHLIGHT
- OVERLAY
- ARTWORK(默认)
- BORDER
- BACKGOUND
(7)窗体移动
想要窗体可移动,需要设置如下三个地方:
- 将Frame属性movable和MouseEnable设置为true
- 注册拖放事件(一般在OnLoad中)frame:RegisterForDrag(button)
- 添加OnDragStart和OnDragStop事件处理self:StartMoving()和self:StopMovingOrSizing()
二、控件
(1)Button
<Button name="$parentTestButton" text="Test:)" inherits="UIPanelButtonTemplate"> <Size> <!--尺寸--> <AbsDimension x="96" y="32"/> </Size> <Anchors> <!--锚点--> <Anchor point="CENTER"/> </Anchors> <Scripts> <OnLoad> <!--加载--> self:RegisterForClicks( "LeftButtonUp", "RightButtonUp", "MiddleButtonDown" ) </OnLoad> <OnClick> <!--点击 function(self, button)--> print("Clicked with", button) </OnClick> </Scripts> </Button>
注,这里的inherits继承了原生UIPanelButtonTemplate,我们也可以自定义一个Template,只需要将Button的virtual属性设置为true(其他控件同理):
<Button name="Template_Button" virtual="true">
(2)ScrollFrame
<ScrollFrame name="$parentScrollFrame inherits="FauxScrollFrameTemplate"> <Size> <!--尺寸--> <AbsDimension x="96" y="32"/> </Size> <Anchors> <!--锚点--> <Anchor point="TOPRIGHT"/> </Anchors> <Scripts> <OnVerticalScroll> <!--滑动--> FauxScrollFrame_OnVerticalScroll(self, offset, 24, Poker.Update) </OnVerticalScroll> <OnMouseWheel> <!--滚动--> ScrollFrameTemplate_OnMouseWheel(PokerScrollFrame, delta) </OnMouseWheel> </Scripts> </ScrollFrame>
ScrollFrame可以直接嵌入<Frames>标签使用。
(3)Static Popup Dialog接收邀请或死亡释放时的弹框都是Static Popup Dialog
StaticPopupDialogs["TEST"] = { --声明dialog text = "Hello, World!", button1 = "接受", button2 = "拒绝", OnAccept = function(self) print("accept!") end OnCancel = function(self) print("Cancel!") end timeout = 0 --0代表无计时 } StaticPopup_Show("TEST") --弹出dialog
(4)Edit Box
<EditBox name="$parentTableName" letters="25"> <Size> ... </Size> <Anchors> ... <Anchors> <FontString inherits="GameFontHighlight"/> </EditBox>
EditBox没有现成的Template可用,需要自行通过<Layers>添加材质<Texture>。
(5)Slider
<Slider name="$parentSlider" minValue="2" maxValue="10" defaultValue="10" valueStep="1" inherits="OptionSliderTemplate"> <Size> ... </Size> <Anchors> ... <Anchors> <Scripts> <OnLoad> <!--加载--> getglobal(self:GetName().."Low"):SetText("2") getglobal(self:GetName().."High"):SetText("10") </OnLoad> <OnValueChanged> <!--值改变--> getglobal(self:GetName().."Text"):SetFormattedText(POKER_MAX, value) </OnValueChanged> </Scripts> </Slider>
其中POKER_MAX是定义在local文件
POKER_MAX = "最多:%d"
(6)Check Button
<CheckButton name="$parentCheckButton" inherits="OptionsCheckButtonTemplate"> <Anchors> <Anchor point="TOPLEFT" relativePoint="BOTTOMLEFT" relativeTo="$parentBigBlind"> <Offset> <AbsDimension x="0" y="-5"/> </Offset> </Anchor> </Anchors> <Scripts> <OnLoad> getglobal(self:GetName().."Text"):SetText(POKER_CHECKBUTTON) </OnLoad> </Scripts> </CheckButton>
其中,POKER_CHECKBUTTON定义在local文件
POKER_CHECKBUTTON = "允许"