using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using RecrownedAthenaeum.Camera; using RecrownedAthenaeum.Render; using RecrownedAthenaeum.ScreenSystem; namespace RecrownedAthenaeum.UI.Modular { /// /// Contains a group of modules and has its own relative coordinate system. /// public class UIModuleGroup : UIModule { List modules = new List(); Rectangle scissorBounds; RasterizerState scissorRasterizer; SpriteBatchSettings spriteBatchSettings; /// /// Camera used by the module for cropping. /// public Camera2D camera; /// /// Creates a module group. /// /// Whether or not to crop out of bounds. Default is false. /// What camera to use for cropping. Default is null and will use 's camera if crop is enabled. /// The settings to be used that begins the batch. public UIModuleGroup(bool crop = false, Camera2D camera = null, SpriteBatchSettings? spriteBatchSettings = null) { if (spriteBatchSettings == null) spriteBatchSettings = Configuration.spriteBatchSettings; if (crop && camera == null) camera = Configuration.Camera2D; this.spriteBatchSettings = spriteBatchSettings.Value; this.camera = camera; if (crop) { scissorRasterizer = new RasterizerState(); scissorRasterizer.ScissorTestEnable = true; scissorBounds = new Rectangle(); } } /// /// Draws this group of modules. /// /// Batch used to draw the group. public override void Draw(SpriteBatch batch) { if (scissorBounds != null) { batch.End(); spriteBatchSettings.BeginSpriteBatch(batch); scissorBounds.Width = situation.Width; scissorBounds.Height = situation.Height; scissorBounds.X = situation.X; scissorBounds.Y = situation.Y; Rectangle scissor = scissorBounds; scissorBounds = batch.GraphicsDevice.ScissorRectangle; batch.GraphicsDevice.ScissorRectangle = scissor; } foreach (UIModule module in modules) { int offsetX = module.situation.X; int offsetY = module.situation.Y; module.situation.X = situation.X + offsetX; module.situation.Y = situation.Y + offsetY; module.Draw(batch); module.situation.X = offsetX; module.situation.Y = offsetY; } if (scissorBounds != null) { batch.GraphicsDevice.ScissorRectangle = scissorBounds; batch.End(); spriteBatchSettings.BeginSpriteBatch(batch); } } /// /// Updates the group of modules. /// /// Game time used. public override void Update(GameTime gameTime) { foreach (UIModule module in modules) { module.Update(gameTime); } } /// /// Adds module(s) to this group. /// /// The module(s) to add. public void AddModule(params UIModule[] addModules) { foreach (UIModule module in addModules) { if (modules.Contains(module)) { throw new InvalidOperationException(module.ToString() + " already exists in " + this.ToString()); } module.parent = this; modules.Add(module); } } /// /// Removes given module from group. /// /// module to remove. public void RemoveModule(UIModule module) { module.parent = null; modules.Remove(module); } /// /// Updates the keyboard state of the modules in this group. /// /// The new state. /// Whether or not to continue updating the other listeners. public override bool KeyboardStateChanged(KeyboardState state) { foreach (UIModule module in modules) { module.KeyboardStateChanged(state); } return base.KeyboardStateChanged(state); } /// /// Updates the moues state of the modules in this group. /// /// The new state. /// Whether or not to continue updating other listeners. public override bool MouseStateChanged(MouseState state) { foreach (UIModule module in modules) { module.MouseStateChanged(state); } return base.MouseStateChanged(state); } } }