14.滑动条UISlider类

滑动条可以用来方便地在一定范围中改变一个值的大小,在Winform中叫做TrackBar。好像在NeoForce Controls(http://www.tomshane.cz/neoforce/default.aspx)中并没有实现滑动条,所以本控件使用的图片来自于DirectSDK:

滑动条使用的图像

我只使用了下方的滑动条轨道和滑块的图像。

滑动条需要实现的主要功能是:

水平滑动条和竖直滑动条大部分行为是类似的,所以将它们的共性封装成UISliderBase基类,将逻辑包含在基类中,而界面代码写在继承的UIHSlider类和UIVSlider类中,这样以后也可以方便地实现斜向的滑动条或仪表盘等。注意:Winform中的TrackBar是通过Orientation属性改变水平还是竖直模式的,如果你曾下载过2010年1月6日发布的StunEngine0.3版本,会发现我就是这样做的,只编写了一个UISlider类,设置SliderMode枚举决定是水平滑动条还是竖直滑动条,但后来发现这样做虽然代码量较小,但可读性和扩展性较差,所以进行了重构。

下面是基类UISliderBase的代码:

namespace StunEngine.SceneNodes.UI
{
    /// <summary>
    /// 滑动条抽象基类,水平滑动条和竖直滑动条从这个类继承。
    /// </summary>
    public abstract class UISliderBase:UISceneNode
    {
        成员变量和构造函数

        属性  
      
        事件相关处理程序
    }
}

而水平滑动条从基类继承,代码如下:

namespace StunEngine.SceneNodes.UI
{
    /// <summary>
    /// 水平滑动条
    /// </summary>
    public class UIHSlider:UISliderBase  
    {
        /// <summary>
        /// 创建一个默认水平滑动条
        /// </summary>
        /// <param name="engine">引擎</param>
        /// <param name="setScene">所属场景</param>
        public UIHSlider(StunXnaGE engine, Scene setScene)
            : base(engine, setScene, Vector2.Zero, "Textures/UI/UIDxutcontrols", DefaultSliderRailSize, DefaultSliderRailRect, DefaultSliderButtonSize, DefaultSliderButtonRect, DefaultSliderButtonRect, DefaultSliderButtonRect)
        {
            //设置水平滑动条滑块的位置
            this.sliderButtonPosition = new Vector2(- sliderButtonSize.X / 2, 0);        
        }        

        public override void Update(GameTime gameTime)
        {
            if (isVisible)
            {
                //如果鼠标在滑动条上且左键按下           
                if (isMouseInside && Input.MouseLeftButtonPressed)
                {
                    isSliding = true;

                    float value = 0;
                    //计算滑动条的值                    
                    value = minValue +((int)(System.Math.Round((Input.MousePos.X - position.X) * tickFrequency / sliderRailSize.X))*(maxValue - minValue)/tickFrequency);
                    //不让value值超出范围
                    if (value < minValue )
                        value = minValue ;
                    else if (value > maxValue)
                        value = maxValue;
                    
                    //如果值变化则重新设置新值并引发ValueChanged事件
                    if (this.value != value )
                    {
                        this.value = value;
                        OnValueChanged();
                    }                   
                }
                else
                    isSliding = false;
            }

            base.Update(gameTime);
        }

        /// <summary>
        /// 绘制滑动条
        /// </summary>
        public override void Draw(GameTime gameTime,bool useReflection)
        {
            if (isVisible)
            {
                // 获取图像淡入淡出的透明颜色
                alphaTextureColor = new Color(color, scene.TransitionAlpha); 

                //绘制滑动条轨道轨道
                StunXnaGE.SpriteBatch.Draw(material.Textures[0], new Rectangle((int)position.X, (int)(position.Y + size.Y / 2 - sliderRailSize.Y / 2), (int)sliderRailSize.X, (int)sliderRailSize.Y), sliderRailRect, alphaTextureColor, rotation, origin, spriteEffect, layerDepth);
                
                //根据鼠标移入还是按下设置滑块图像源矩阵                
                Rectangle buttonRect = isMouseInside || (uiManager.ActiveControl == this) ? ((Input.MouseLeftButtonPressed && isMouseInside) ? sliderButtonRectClicked : sliderButtonRectHighlight) : sliderButtonRectOrigin;       
                //绘制滑块
                StunXnaGE.SpriteBatch.Draw(material.Textures[0], new Rectangle((int)sliderButtonPosition.X, (int)position.Y, (int)sliderButtonSize.X, (int)sliderButtonSize.Y), buttonRect, alphaTextureColor, rotation, origin, spriteEffect, layerDepth);                
                
            }
        }

        事件相关处理程序

        单元测试
    }
}

竖直滑动条的代码与水平滑动条的代码类似,不再赘述,最主要的不同是在绘制轨道和滑块时需要将它们的Rotation属性从0变为MathHelper.PiOver2,表示顺时针旋转90度,这样做可以重用轨道和滑块的图像,无需再建立一个竖直轨道和竖直滑块的图像。

单元测试截图如下:

单元测试截图


发布时间:2010/1/25 上午8:39:43  阅读次数:9231

2006 - 2024,推荐分辨率 1024*768 以上,推荐浏览器 Chrome、Edge 等现代浏览器,截止 2021 年 12 月 5 日的访问次数:1872 万 9823 站长邮箱

沪 ICP 备 18037240 号-1

沪公网安备 31011002002865 号