11. 按钮基类UIButtonBase.cs和按钮类UIButton.cs
下面几个教程需要创建按钮、复选框和单选框,这几个控件的行为是类似的,所以比较好的方法是创建一个按钮基类,而按钮类,复选框类和单选框类从这个基类继承,所以需要将这三个类的共有功能抽象出来封装成一个基类,先归纳一下按钮需要实现的功能:
- 绘制按钮背景,这个背景有三个状态:初始状态,鼠标移入时的状态,鼠标点击时的状态。
- 绘制按钮上的文字,文字颜色有两个状态:初始颜色和高亮时的颜色。
- 按钮的鼠标点击事件已经在基类UISceneNode.cs中实现了,按钮控件还需要一个额外的属性:文字的对齐方式,这里只实现了居中对齐和向左对齐。
而复选框和单选框的功能是类似的,不同之处在于背景图像位于文字的左侧而不是在文字的下面。 提取出共性后,按钮基类代码如下:
namespace StunEngine.SceneNodes.UI
...{
/**//// <summary>
/// 按钮控件基类,按钮、复选框、单选框都是从这个类继承的
/// </summary>
public abstract class UIButtonBase:UISceneNode
...{
/**//// <summary>
/// 控件上显示的文字
/// </summary>
protected string text;
/**//// <summary>
/// 按钮文字颜色
/// </summary>
protected Color textColor;
/**//// <summary>
/// 按钮文字高亮颜色
/// </summary>
protected Color textColorHighlight;
/**//// <summary>
/// 文字使用的字体
/// </summary>
protected SpriteFont font;
/**//// <summary>
/// 控件普通状态的源矩形
/// </summary>
protected Rectangle rectSourceOrigin;
/**//// <summary>
/// 控件高亮状态的源矩形
/// </summary>
protected Rectangle rectSourceHighlight;
/**//// <summary>
/// 创建一个新UIButtonBase对象,内部方法
/// </summary>
/// <param name="engine">引擎</param>
/// <param name="setScene">此控件所属的scene</param>
/// <param name="setPosition">2D屏幕位置</param>
/// <param name="setTextureName">包含路径的背景纹理的名称</param>
/// <param name="setSize">2D屏幕大小</param>
/// <param name="setText">按钮上的文字</param>
/// <param name="setFont">字体</param>
/// <param name="setTextColor">普通状态的文字颜色</param>
/// <param name="setTextColorHighlight">高亮状态的文字颜色</param>
/// <param name="setRectOrigin">普通状态图像源矩形</param>
/// <param name="setRectHighlight">高亮状态的图像源矩形</param>
/// <param name="setRectClicked">鼠标点击状态的图像源矩形</param>
internal UIButtonBase(StunXnaGE engine, Scene setScene, Vector2 setPosition, string setTextureName, Vector2 setSize, string setText, SpriteFont setFont, Color setTextColor, Color setTextColorHighlight, Rectangle setRectOrigin, Rectangle setRectHighlight)
: base(engine, setScene, setPosition, setTextureName)
...{
this.size = setSize;
this.text = setText;
this.font = setFont;
this.textColor = setTextColor;
this.textColorHighlight = setTextColorHighlight;
this.rectSourceOrigin = setRectOrigin;
this.rectSourceHighlight = setRectHighlight;
}
属性#region 属性
/**//// <summary>
/// 获取或设置按钮上的文字
/// </summary>
public virtual string Text
...{
get ...{ return text; }
set ...{ text = value; }
}
/**//// <summary>
/// 获取或设置文字原始颜色
/// </summary>
public Color TextColor
...{
get ...{ return textColor; }
set ...{ textColor = value; }
}
/**//// <summary>
/// 获取或设置文字高亮颜色
/// </summary>
public Color TextColorHighlight
...{
get ...{ return textColorHighlight; }
set ...{ textColorHighlight = value; }
}
/**//// <summary>
/// 获取或设置文字使用的字体
/// </summary>
public virtual SpriteFont Font
...{
get ...{ return font; }
set ...{ font = value; }
}
/**//// <summary>
/// 获取或设置纹理的普通状态的源矩形
/// </summary>
public Rectangle RectSourceOrigin
...{
get ...{ return (Rectangle)rectSourceOrigin; }
set ...{ rectSourceOrigin = value; }
}
/**//// <summary>
/// 获取或设置纹理高亮状态的源矩形
/// </summary>
public Rectangle RectSourceHighlight
...{
get ...{ return rectSourceHighlight; }
set ...{ rectSourceHighlight = value; }
}
#endregion
}
}
在UISceneNode类的基础上,UIButton类添加了一个文字对齐方式的textAlign变量和表示鼠标点击时背景图片矩形的rectSourceClicked变量,当然还包括绘制按钮的具体代码:
namespace StunEngine.SceneNodes.UI
...{
/**//// <summary>
/// 文字对齐方式枚举
/// </summary>
public enum TextAlign
...{
MiddleLeft,
MiddleCenter
}
/**//// <summary>
/// 按钮控件
/// </summary>
public class UIButton:UIButtonBase
...{
成员变量和构造函数#region 成员变量和构造函数
//默认值
private static readonly Vector2 DefaultButtonSize = new Vector2 (116,38);
private static readonly Rectangle DefaultRectSource=new Rectangle (0, 0, 64, 24);
private static readonly Rectangle DefaultRectHighlight=new Rectangle (64, 0, 64, 24);
private static readonly Rectangle DefaulRectClicked = new Rectangle(64, 24, 64, 24);
private static readonly Color DefaultTextColor=Color .White ;
private static readonly Color DefaultTextHighlight=Color.Red ;
/**//// <summary>
/// 文字的对齐方式,默认为居中对齐
/// </summary>
protected TextAlign textAlign = TextAlign.MiddleCenter;
/**//// <summary>
/// 鼠标按下时纹理的源矩形
/// </summary>
protected Rectangle rectSourceClicked;
/**//// <summary>
/// 创建一个默认按钮
/// </summary>
/// <param name="engine">引擎</param>
/// <param name="setScene">所属场景</param>
public UIButton(StunXnaGE engine, Scene setScene):this(engine ,setScene,"Textures/UI/UIButton")
...{
}
/**//// <summary>
/// 使用自定义的背景创建一个按钮,你也可以将纹理名称设为null创建一个只有文字的按钮。
/// </summary>
/// <param name="engine">引擎</param>
/// <param name="setScene">所属Scene</param>
/// <param name="setTextureName">纹理名称</param>
public UIButton(StunXnaGE engine, Scene setScene, string setTextureName)
: this(engine, setScene, Vector2.Zero, setTextureName, DefaultButtonSize, "Button", engine.DefaultFont, DefaultTextColor, DefaultTextHighlight, DefaultRectSource, DefaultRectHighlight, DefaulRectClicked)
...{
}
/**//// <summary>
/// 创建一个新UIButton对象,内部方法,只能在引擎内部调用。
/// </summary>
/// <param name="engine">引擎</param>
/// <param name="setScene">此控件所属的scene</param>
/// <param name="setPosition">2D屏幕位置</param>
/// <param name="setTextureName">包含路径的背景纹理的名称</param>
/// <param name="setSize">2D屏幕大小</param>
/// <param name="setText">按钮上的文字</param>
/// <param name="setFont">字体</param>
/// <param name="setTextColorOrigin">文字原始颜色</param>
/// <param name="setTextColorHighlight">高亮状态的文字颜色</param>
/// <param name="setRectOrigin">普通状态图像源矩形</param>
/// <param name="setRectHighlight">高亮状态的图像源矩形</param>
/// <param name="setRectClicked">鼠标点击状态的图像源矩形</param>
internal UIButton(StunXnaGE engine, Scene setScene, Vector2 setPosition, string setTextureName, Vector2 setSize, string setText, SpriteFont setFont, Color setTextColor, Color setTextColorHighlight, Rectangle setRectOrigin, Rectangle setRectHighlight, Rectangle setRectClicked)
: base(engine, setScene, setPosition, setTextureName, setSize, setText, setFont, setTextColor, setTextColorHighlight, setRectOrigin, setRectHighlight)
...{
this.rectSourceClicked = setRectClicked;
//如果不包含背景图片,则按钮的大小就是文字的大小
if (setTextureName == null)
this.size = new Vector2(setFont.MeasureString(setText).X, setFont.MeasureString(setText).Y);
}
#endregion
属性#region 属性
/**//// <summary>
/// 获取或设置文字的对齐方式
/// </summary>
public TextAlign TextAlign
...{
get ...{ return textAlign; }
set ...{ textAlign = value; }
}
/**//// <summary>
/// 获取或设置鼠标按下时纹理的源矩形
/// </summary>
public Rectangle RectSourceClicked
...{
get ...{ return rectSourceClicked; }
set ...{ rectSourceClicked = value; }
}
/**//// <summary>
/// 获取或设置按钮上的文字
/// </summary>
public override string Text
...{
get
...{
return base.Text;
}
set
...{
base.Text = value;
//如果不包含背景图片,则按钮的大小就是文字的大小
if (colorTextureName == null)
this.size = new Vector2(font.MeasureString(text).X, font.MeasureString(text).Y);
}
}
#endregion
/**//// <summary>
/// 绘制按钮
/// </summary>
public override void Draw(GameTime gameTime,bool useReflection)
...{
if (isVisible)
...{
//如果按钮背景图片不为null,则绘制背景
if (ColorTextureName != null)
...{
//获取图像淡入淡出的透明颜色
alphaTextureColor = new Color(color, scene.TransitionAlpha);
//根据鼠标移入还是按下设置图像源矩阵
Rectangle rect = isMouseInside || (uiManager.ActiveControl == this) ? ((Input.MouseLeftButtonPressed&&isMouseInside)?rectSourceClicked: rectSourceHighlight): rectSourceOrigin;
//绘制按钮背景图像
StunXnaGE.SpriteBatch.Draw(material.Textures[0], new Rectangle((int)position.X, (int)position.Y, (int)size.X, (int)size.Y), rect, alphaTextureColor, rotation, origin, spriteEffect, layerDepth);
}
//如果按钮文字不为null,则绘制文字
if (text != null)
...{
Color textColor = isMouseInside || (uiManager.ActiveControl == this) ? textColorHighlight : TextColor;
// 设置淡入淡出的透明度
Color alphaTextColor = new Color(textColor.R, textColor.G, textColor.B, scene.TransitionAlpha);
//如果文字的对齐方式为MiddleCenter
if (textAlign == TextAlign.MiddleCenter)
StunXnaGE.SpriteBatch.DrawString(font, text, new Vector2(position.X + size.X / 2 - font.MeasureString(text).X / 2, position.Y + size.Y / 2 - font.MeasureString(text).Y / 2), alphaTextColor, rotation, origin, 1.0f, spriteEffect, layerDepth);
//如果文字的对齐方式为MiddleLeft
else if (textAlign == TextAlign.MiddleLeft)
StunXnaGE.SpriteBatch.DrawString(font, text, new Vector2(position.X, position.Y + size.Y / 2 - font.MeasureString(text).Y / 2), alphaTextColor, rotation, origin, 1.0f, spriteEffect, layerDepth);
}
}
}
单元测试#region 单元测试
#if DEBUG
/**//// <summary>
/// 测试UIButton类
/// </summary>
public static void TestUIButton()
...{
UIButton btnStandard = null;
UIButton btnOnlyText = null;
UIButton btnCustom = null;
TestGame.Start("测试UIButton类",
delegate
...{
//创建一个默认按钮,按钮上的文字默认为"Button",按钮的默认大小为116*38,默认文字颜色为白色,默认文字高亮颜色为红色
btnStandard = new UIButton(TestGame.engine, TestGame.scene);
btnStandard.Position = new Vector2(100, 100);
TestGame.scene.AddNode(btnStandard);
//创建一个只有文字的按钮,设置文字为“OnlyText”,文字颜色为青色,文字高亮颜色为蓝色
btnOnlyText =new UIButton (TestGame.engine, TestGame.scene,null );
btnOnlyText.Position = new Vector2(100, 200);
btnOnlyText.Text = "OnlyText";
btnOnlyText.TextColor = Color.Cyan;
btnOnlyText.TextColorHighlight = Color.Blue;
TestGame.scene.AddNode(btnOnlyText);
//创建一个使用自定义背景图片的按钮
btnCustom= new UIButton(TestGame.engine, TestGame.scene, "Textures\\UI\\UIScrollBar");
btnCustom.RectSourceOrigin = new Rectangle(0, 0, 16, 16);
btnCustom.RectSourceHighlight = new Rectangle(16, 0, 16, 16);
btnCustom.RectSourceClicked = new Rectangle(32, 0, 16, 16);
btnCustom.Size = new Vector2(32, 32);
btnCustom.Text = null;
btnCustom.Position = new Vector2(100, 300);
TestGame.scene.AddNode(btnCustom);
//关闭相机控制器
TestGame.scene.fpsCamCtrl.Enabled = false;
});
}
#endif
#endregion
}
}
运行单元测试的程序截图如下:
发布时间:2010/1/18 上午8:50:28 阅读次数:7607