using RecrownedAthenaeum.Input; using RecrownedAthenaeum.Assets; using RecrownedAthenaeum.Render; using RecrownedAthenaeum.UI.SkinSystem; using System; using System.Collections.Generic; using System.Linq; using RecrownedAthenaeum.Types; namespace RecrownedAthenaeum.UI.BookSystem { /// /// Contains the pages. /// public class Book : IInputListener { readonly AssetManager assets; readonly ISkin skin; Page targetPage; int width, height; Dictionary pages = new Dictionary(); List orderedPages = new List(); /// /// The camera to use to change between pages. /// public Camera2D camera; private BasicScissor basicScissor; /// /// Creates a book. /// /// that holds the assets that are to be used in the pages for this book during initialization. /// The skin that will be passed to pages during their initialization. /// Camera to move to change pages. public Book(AssetManager assets, ISkin skin, Camera2D camera) { this.assets = assets; this.skin = skin; this.camera = camera ?? throw new ArgumentNullException("Camera can't be null since book needs a camera to move to change between the slides (pages)."); this.basicScissor = new BasicScissor(); } /// /// Should be called whenever a valid camera and dimensions for the book exist. /// Initializes book with given parameters. /// Generally used with a and called in the function. /// /// Camera to move to change pages. /// Dimensions of the book and the dimensions the pages will use. public void Initiate(Camera2D camera, Rectangle dimensions) { this.camera = camera; } /// /// Applies the size if the book's pages. /// /// The width of one page. /// The height of one page. public void ApplySize(int width, int height) { if (this.width == width && this.height == height) return; this.width = width; this.height = height; for (int pageIndex = 0; pageIndex < pages.Count; pageIndex++) { Page page = orderedPages[pageIndex]; if (page.Boundaries.Width != width || page.Boundaries.Height != height) { page.requiresSizeUpdate = true; } } } /// /// Draws the pages. /// /// Batch used to draw. public void Draw(ConsistentSpriteBatch batch) { for (int pageIndex = 0; pageIndex < pages.Count; pageIndex++) { orderedPages[pageIndex].Draw(batch); } } /// /// Updates the book. /// /// Snapshot of information of the game time. public void Update(GameTime gameTime) { if (targetPage != null) { Vector2 position; Rectangle targetBounds = targetPage.Boundaries; position.X = targetBounds.X + (targetBounds.Width * 0.5f); position.Y = targetBounds.Y + (targetBounds.Height * 0.5f); camera.LinearInterpolationToPosition(0.4f, position, (float)gameTime.ElapsedGameTime.TotalSeconds); if (camera.Position == position) { targetPage = null; } } for (int pageIndex = 0; pageIndex < pages.Count; pageIndex++) { Page page = pages.ElementAt(pageIndex).Value; if (page.requiresSizeUpdate) page.ApplySize(width, height); page.Update(gameTime); } } /// /// Adds the page(s). /// /// The page(s) to add. public void AddPages(params Page[] pages) { foreach (Page page in pages) { orderedPages.Add(page); this.pages.Add(page.name, page); page.Initialize(assets, skin, basicScissor); } } /// /// Removes the page. /// /// Page to remove. public void RemovePage(Page page) { RemovePage(page.name); } /// /// Removes the page. /// /// Name of page to remove. public void RemovePage(string name) { orderedPages.Remove(pages[name]); pages.Remove(name); } /// /// Removes all pages. /// public void ClearPages() { orderedPages.Clear(); pages.Clear(); } /// /// Perform a step of linear interpolation to the given page. /// /// The page to lerp to. public void LerpToPage(Page page) { targetPage = page; } /// /// Goes to page instantly. /// /// Page to go to. public void GoToPage(Page page) { Rectangle targetBounds = page.Boundaries; camera.position.X = targetBounds.X + (targetBounds.Width * 0.5f); camera.position.Y = targetBounds.Y + (targetBounds.Height * 0.5f); } /// /// Passes the new keyboard state down to each page in order of when it was added. /// /// /// True if the state change should to trigger further input listeners. public bool KeyboardStateChanged(KeyboardState state) { for (int pageIndex = 0; pageIndex < pages.Count; pageIndex++) { Page page = orderedPages[pageIndex]; if (!page.KeyboardStateChanged(state)) return false; } return true; } /// /// Passes the new mouse state down to each page in order of when it was added. /// /// /// True if the state change should to trigger further input listeners. public bool MouseStateChanged(MouseState state) { for (int pageIndex = 0; pageIndex < pages.Count; pageIndex++) { Page page = orderedPages[pageIndex]; if (!page.MouseStateChanged(state)) return false; } return true; } } }