15.滚动条UIScrollBar类

滚动条的行为与滑动条是非常相像的,只不过还需要绘制两个带箭头的按钮,而且滑块可以平滑移动,而不是像滑动条那样只能间断移动。滚动条使用的图像如下:

滚动条使用的图像

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

水平滚动条和竖直滚动条大部分行为是类似的,所以将它们的共性封装成UIScrollBarBase基类,将逻辑包含在基类中,而界面代码写在继承的UIHScrollBar类和UIVScrollBar类中。下面是基类UIScrollBarBase的代码:

/// <summary>
    /// 滚动条基类,水平滚动条和竖直滚动条从这个类继承
    /// </summary>
    public abstract class UIScrollBarBase:UISceneNode
    {
        成员变量和构造函数

        属性      

        事件相关处理程序
    }

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

/// <summary>
    /// 水平滚动条
    /// </summary>
    public class UIHScrollBar:UIScrollBarBase
    {
        成员变量和构造函数

        public override void Update(GameTime gameTime)
        {
            if (isVisible)
            {
                //设置滑动条上按钮的位置,计算滑动条的值并引发ValueChanged事件           
                if (isMouseInside && Input.MouseLeftButtonPressed)
                {
                    isScrolling = true;

                    //根据鼠标移动改变滑块的水平位置
                    sliderButtonPosition.X = position.X + buttonWidth;
                    sliderButtonPosition.X += Input.MousePos.X - position.X - buttonWidth- sliderButtonSizeX / 2;

                    //不让滑块超出滑动条边界
                    if (sliderButtonPosition.X < position.X + buttonWidth)
                        sliderButtonPosition.X = position.X + buttonWidth;
                    else if (sliderButtonPosition.X > position.X + buttonWidth + sliderRailSizeX - sliderButtonSizeX)
                        sliderButtonPosition.X = position.X + buttonWidth + sliderRailSizeX - sliderButtonSizeX;

                    int value = 0;
                    value = (int)System.Math.Round((Input.MousePos.X - position.X - buttonWidth - sliderButtonSizeX / 2) * maxStep / (sliderRailSizeX - sliderButtonSizeX));
                    
                    //不让value的值超出范围
                    if (value < 0)
                        value = 0;
                    else if (value > maxStep)
                        value = maxStep;

                    //如果值变化则重新设置新值并引发ValueChanged事件
                    if (this.value != value)
                    {
                        this.value = value;
                        OnValueChanged();
                    }
                }
                else
                    isScrolling = 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)(sliderRailPosition.X) , (int)(sliderRailPosition.Y), (int)sliderRailSizeX, (int)buttonWidth), 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)sliderButtonSizeX, (int)buttonWidth), buttonRect, alphaTextureColor, rotation, origin, spriteEffect, layerDepth);              

                //绘制滑块上的摩擦条,如果滑块长度小于滚动条高度则无需绘制摩擦条
                if(sliderButtonSizeX >size .Y)
                    StunXnaGE.SpriteBatch.Draw(material.Textures[0], new Rectangle((int)(sliderButtonPosition.X + sliderButtonSizeX / 2 - buttonWidth / 2), (int)sliderButtonPosition.Y, (int)buttonWidth, (int)buttonWidth), sliderButtonGlyphRect, color, rotation, origin, spriteEffect, layerDepth);
            }

        }

        事件相关处理程序

        单元测试
    }

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

单元测试截图如下:

单元测试截图


发布时间:2010/1/28 上午8:32:23  阅读次数:7781

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

沪 ICP 备 18037240 号-1

沪公网安备 31011002002865 号