/*
* 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
}
}