/* * GUIScrollBar.cs * Authors: Mike DeMauro * Copyright (c) 2007-2008 Cornell University This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ using System; using System.Collections.Generic; using System.Text; using tAC_Engine.GUI; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Util; namespace tAC_Engine.GUI { /// /// Defines the scroll bar GUI component /// public class GUIScrollBar : GUIContainer { #region Fields // The track height private float trackHeight; /// /// The pixel texture to use /// protected Texture2D mPixel; /// /// The color for the background /// protected Color mBackgroundColor = Color.White; /// /// The button component for the up button /// protected GUIButton mUpButton = new GUIButton(); /// /// The button component for the down button /// protected GUIButton mDownButton = new GUIButton(); /// /// The button component for the scroll button /// protected GUIButton mScrollButton = new GUIButton(); /// /// Whether or not the scrollbar is currently being dragged /// protected bool mDragging = false; /// /// Current position of the scroll bar /// protected int mScrollPosition = 0; /// /// Lowest position the scroll bar can go /// protected int mMinScrollPosition = 0; /// /// Highest postiion the scroll bar can go /// protected int mMaxScrollPosition = 0; /// /// The amount the scroll bar moves every time it is moved without dragging /// protected int mLargeScrollAmount = 5; #endregion #region Properties /// /// Gets/Sets the position of the scroll bar GUI /// public override Vector2 Position { get { return base.Position; } set { base.Position = value; updatePositions(); } } /// /// Gets/Sets the screen offset for the scroll bar GUI /// public override Vector2 ScreenOffset { get { return base.ScreenOffset; } set { base.ScreenOffset = value; updatePositions(); } } /// /// Gets/Sets the size of the scroll bar GUI /// public override Vector2 Size { get { return base.Size; } set { base.Size = value; updateSizes(); } } /// /// Gets/Sets the visibility of the scrollbar /// public override bool Visible { get { return base.Visible; } set { mUpButton.Visible = value; mDownButton.Visible = value; mScrollButton.Visible = value; base.Visible = value; } } /// /// Sets the texture to use when the up button is up /// public string UpButtonTextureUpName { set { mUpButton.ButtonUpName = value; } } /// /// Sets the texture to use when the up button is down /// public string UpButtonTextureDownName { set { mUpButton.ButtonDownName = value; } } /// /// Sets the texture to use when the up button is over /// public string UpButtonTextureOverName { set { mUpButton.ButtonOverName = value; } } /// /// Sets the texture to use when the down button is up /// public string DownButtonTextureUpName { set { mDownButton.ButtonUpName = value; } } /// /// Sets the texture to use when the down button is down /// public string DownButtonTextureDownName { set { mDownButton.ButtonDownName = value; } } /// /// Sets the texture to use when the down button is over /// public string DownButtonTextureOverName { set { mDownButton.ButtonOverName = value; } } /// /// Gets/Sets the position of the scroll bar component /// public int ScrollPosition { get { return mScrollPosition; } set { mScrollPosition = value; } } /// /// Gets/Sets the minimum scroll position of the scroll bar component /// public int MinScrollPosition { get { return mMinScrollPosition; } set { mMinScrollPosition = value; } } /// /// Gets/Sets the maximum position of the scroll bar component /// public int MaxScrollPosition { get { return mMaxScrollPosition; } set { mMaxScrollPosition = value; } } /// /// Gets/Sets the amount scrolled when track is clicked /// public int LargeScrollAmount { get { return mMaxScrollPosition; } set { mMaxScrollPosition = value; } } #endregion #region Creation /// /// Constructor /// public GUIScrollBar() { Add(mUpButton); Add(mDownButton); Add(mScrollButton); } #endregion #region Initialization /// /// Initializes the component. Override this method to load any non-graphics /// resources and query for any required services. /// public override void Initialize() { updatePositions(); updateSizes(); mUpButton.ButtonPressed += new EventHandler(mUpButton_ButtonPressed); mDownButton.ButtonPressed += new EventHandler(mDownButton_ButtonPressed); mScrollButton.ButtonPressed += new EventHandler(mScrollButton_ButtonPressed); base.Initialize(); } #endregion #region Management /// /// Loads all the necessary information for content dependent objects /// public override void LoadContent() { if (mParentScreen != null) { // create pixel mPixel = new Texture2D(mParentScreen.GraphicsDevice, 1, 1, 1, TextureUsage.None, SurfaceFormat.Color); Color[] pixels = new Color[1]; pixels[0] = Color.White; mPixel.SetData(pixels); } base.LoadContent(); } #endregion #region Update /// /// Updates the state of the scroll bar GUI /// /// The time that has passed in game public override void Update(GameTime gameTime) { if (mParentScreen != null) { if (mDragging) { float newY = mParentScreen.InputHandler.MouseLocation.Y; if (newY > mDownButton.Bounds.Top - mScrollButton.Size.Y) { newY = mDownButton.Bounds.Top - mScrollButton.Size.Y; } else if(newY < mUpButton.Bounds.Bottom) { newY = mUpButton.Bounds.Bottom; } mScrollButton.Position = new Vector2(mScrollButton.Position.X, newY); int newScrollPos = (int)((mScrollButton.Position.Y - mUpButton.Size.Y) / (trackHeight / mMaxScrollPosition)); if (newScrollPos != mScrollPosition) { mScrollPosition = newScrollPos; if (ScrollChanged != null) ScrollChanged.Invoke(this, EventArgs.Empty); } } } //mUpButton.LayerDepth = mLayerDepth + 0.001f; //mDownButton.LayerDepth = mLayerDepth + 0.001f; //mScrollButton.LayerDepth = mLayerDepth + 0.001f; base.Update(gameTime); } /// /// Updates the position of the scroll bar components (as well as the screen tranform) /// protected void updatePositions() { mUpButton.Position = mPosition; mDownButton.Position = new Vector2(mPosition.X, mPosition.Y + mSize.Y - mDownButton.Size.Y); mScrollButton.Position = new Vector2(mPosition.X, mUpButton.Bounds.Bottom + (mScrollPosition * trackHeight / mMaxScrollPosition)); mUpButton.ScreenOffset = mScreenOffset; mDownButton.ScreenOffset = mScreenOffset; mScrollButton.ScreenOffset = mScreenOffset; } /// /// Updates all the sizes of the scroll bar components /// protected void updateSizes() { mUpButton.Size = new Vector2(mSize.X, mSize.X); mDownButton.Size = new Vector2(mSize.X, mSize.X); trackHeight = mSize.Y - mUpButton.Size.Y - mDownButton.Size.Y; mScrollButton.Size = new Vector2(mSize.X, trackHeight / mMaxScrollPosition); updatePositions(); } #endregion #region Event Handling /// /// Event for when the scroll bar has been modified /// public event EventHandler ScrollChanged; /// /// Event that processes when the up button is pressed /// /// The sender of the event /// The associated arguments with the event internal void mUpButton_ButtonPressed(object sender, EventArgs e) { if (mScrollPosition > mMinScrollPosition) { --mScrollPosition; updatePositions(); if (ScrollChanged != null) ScrollChanged.Invoke(this, EventArgs.Empty); } } /// /// Event that processed when the down button is pressed /// /// The sender of the event /// The associated arguments with the event internal void mDownButton_ButtonPressed(object sender, EventArgs e) { if (mScrollPosition < mMaxScrollPosition) { ++mScrollPosition; updatePositions(); if (ScrollChanged != null) ScrollChanged.Invoke(this, EventArgs.Empty); } } /// /// Event that processes when the scroll button is pressed /// /// The sender of the event /// The associated arguments with the event void mScrollButton_ButtonPressed(object sender, EventArgs e) { mDragging = true; } /// /// Handle the given event. /// /// The event to handle. public override bool HandleMouseEvent(MouseInputEvent e) { if (e.EventCode == (int)GUIEventCodes.LEFT_MOUSE_RELEASED && mDragging) { mDragging = false; } else // Check to see if it's within our bounds if (Bounds.Contains(e.X, e.Y)) { // Let a component handle it first if able if (base.HandleMouseEvent(e)) return true; // Evaluate for a left mouse button press if (e.EventCode == (int)GUIEventCodes.LEFT_MOUSE_CLICKED) { // TODO: change scroll position based on track position if (e.Y > mScrollButton.Bounds.Bottom) { mScrollPosition += mLargeScrollAmount; if (mScrollPosition > mMaxScrollPosition) mScrollPosition = mMaxScrollPosition; updatePositions(); } else if (e.Y < mScrollButton.Bounds.Top) { mScrollPosition -= mLargeScrollAmount; if (mScrollPosition < mMinScrollPosition) mScrollPosition = mMinScrollPosition; updatePositions(); } if (ScrollChanged != null) ScrollChanged.Invoke(this, EventArgs.Empty); // Set the event args if they're null if (e.EventArgs == null) { // Set the event args to us e.EventArgs = this; } return true; } } return false; } #endregion #region Draw /// /// Renders the scroll bar Gui /// /// Time that has passed in game public override void Draw(GameTime gameTime) { if (mIsVisible) { // Draw Background Batch.Draw(mPixel, Bounds, mBackgroundColor); base.Draw(gameTime); } } #endregion } }