Stardew_Valley_Mods/GeneralMods/StardustCore/Menus/ModualGameMenu.cs

412 lines
17 KiB
C#

using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using StardewModdingAPI;
using StardewValley;
using StardewValley.Menus;
using StardustCore.UIUtilities;
using StardustCore.UIUtilities.MenuComponents;
using StardustCore.UIUtilities.MenuComponents.ComponentsV1;
namespace StardustCore.Menus
{
// TODO: make buttons to cycle through page
public class ModularGameMenu : IClickableMenuExtended
{
public static SortedDictionary<string, List<KeyValuePair<Button, IClickableMenuExtended>>> StaticMenuTabsAndPages = new SortedDictionary<string, List<KeyValuePair<Button, IClickableMenuExtended>>>();
public string hoverText = "";
public string descriptionText = "";
public Dictionary<Button, IClickableMenuExtended> menuTabsAndPages;
public Button currentButton;
public IClickableMenuExtended currentMenu;
public bool invisible;
public static bool forcePreventClose;
public const int tabsPerPage = 12;
public int currentPageIndex;
public ModularGameMenu()
: base(Game1.viewport.Width / 2 - (800 + IClickableMenu.borderWidth * 2) / 2, Game1.viewport.Height / 2 - (600 + IClickableMenu.borderWidth * 2) / 2, 800 + IClickableMenu.borderWidth * 2, 600 + IClickableMenu.borderWidth * 2, true)
{
//ModCore.ModMonitor.Log("INITIALIZE MENU: ", LogLevel.Alert);
if (Game1.activeClickableMenu == null)
Game1.playSound("bigSelect");
GameMenu.forcePreventClose = false;
this.menuTabsAndPages = new Dictionary<Button, IClickableMenuExtended>();
//ModCore.ModMonitor.Log("INITIALIZE MENU: ", LogLevel.Alert);
foreach (var v in StaticMenuTabsAndPages)
{
//ModCore.ModMonitor.Log("LIST A GO GO", LogLevel.Alert);
foreach (var pair in v.Value)
{
this.AddMenuTab(pair.Key, pair.Value.clone());
//ModCore.ModMonitor.Log("ADD IN A PART", LogLevel.Alert);
}
//this.menuTabsAndPages.Add(v.Key,v.Value.clone());
}
}
public static void AddTabsForMod(IManifest modManifest, List<KeyValuePair<Button, IClickableMenuExtended>> menuComponents)
{
StaticMenuTabsAndPages.Add(modManifest.UniqueID, menuComponents);
}
public void AddMenuTab(Button b, IClickableMenuExtended menu)
{
int count = this.menuTabsAndPages.Count % tabsPerPage;
int xPos = this.xPositionOnScreen + count * 64;
int yPos = this.yPositionOnScreen;
b.bounds = new Rectangle(xPos, yPos, b.bounds.Width, b.bounds.Height);
if (b.extraTextures == null)
{
this.menuTabsAndPages.Add(b, menu);
return;
}
for (int i = 0; i < b.extraTextures.Count; i++)
{
ClickableTextureComponent text = b.extraTextures.ElementAt(i).Key;
Rectangle bounds = new Rectangle(b.bounds.X + text.bounds.X, b.bounds.Y + text.bounds.Y, text.bounds.Width, text.bounds.Height);
text.bounds = bounds;
b.extraTextures[i] = new KeyValuePair<ClickableTextureComponent, ExtraTextureDrawOrder>(text, b.extraTextures.ElementAt(i).Value);
}
this.menuTabsAndPages.Add(b, menu);
}
/// <summary>Get how many pages there should be for the modular menu.</summary>
public int getNumberOfPages()
{
int count = (this.menuTabsAndPages.Count / tabsPerPage);
return count;
}
/// <summary>Takes in the static declared tabs and tries to set the menu tabs to that.</summary>
public ModularGameMenu(int startingTab)
: base(Game1.viewport.Width / 2 - (800 + IClickableMenu.borderWidth * 2) / 2, Game1.viewport.Height / 2 - (600 + IClickableMenu.borderWidth * 2) / 2, 800 + IClickableMenu.borderWidth * 2, 600 + IClickableMenu.borderWidth * 2, true)
{
ModCore.ModMonitor.Log("INITIALIZE MENU: ", LogLevel.Alert);
if (Game1.activeClickableMenu == null)
Game1.playSound("bigSelect");
GameMenu.forcePreventClose = false;
this.menuTabsAndPages = new Dictionary<Button, IClickableMenuExtended>();
ModCore.ModMonitor.Log("INITIALIZE MENU: ", LogLevel.Alert);
foreach (var v in StaticMenuTabsAndPages)
{
ModCore.ModMonitor.Log("LIST A GO GO", LogLevel.Alert);
foreach (var pair in v.Value)
{
this.AddMenuTab(pair.Key, pair.Value.clone());
ModCore.ModMonitor.Log("ADD IN A PART", LogLevel.Alert);
}
//this.menuTabsAndPages.Add(v.Key,v.Value.clone());
}
this.currentPageIndex = startingTab % tabsPerPage;
this.changeTab(startingTab);
}
/// <summary>Takes in the static declared tabs and tries to set the menu tabs to that.</summary>
public ModularGameMenu(string startingTab)
: base(Game1.viewport.Width / 2 - (800 + IClickableMenu.borderWidth * 2) / 2, Game1.viewport.Height / 2 - (600 + IClickableMenu.borderWidth * 2) / 2, 800 + IClickableMenu.borderWidth * 2, 600 + IClickableMenu.borderWidth * 2, true)
{
ModCore.ModMonitor.Log("INITIALIZE MENU: ", LogLevel.Alert);
if (Game1.activeClickableMenu == null)
Game1.playSound("bigSelect");
GameMenu.forcePreventClose = false;
this.menuTabsAndPages = new Dictionary<Button, IClickableMenuExtended>();
ModCore.ModMonitor.Log("INITIALIZE MENU: ", LogLevel.Alert);
foreach (var v in StaticMenuTabsAndPages)
{
ModCore.ModMonitor.Log("LIST A GO GO", LogLevel.Alert);
foreach (var pair in v.Value)
{
this.AddMenuTab(pair.Key, pair.Value.clone());
ModCore.ModMonitor.Log("ADD IN A PART", LogLevel.Alert);
}
//this.menuTabsAndPages.Add(v.Key,v.Value.clone());
}
this.changeTab(this.getTabIndexFromName(startingTab));
}
/// <summary>More modular menu to only have a subset of buttons and pages.</summary>
public ModularGameMenu(int startingTab, Dictionary<Button, IClickableMenuExtended> tabsAndPages) : base(Game1.viewport.Width / 2 - (800 + IClickableMenu.borderWidth * 2) / 2, Game1.viewport.Height / 2 - (600 + IClickableMenu.borderWidth * 2) / 2, 800 + IClickableMenu.borderWidth * 2, 600 + IClickableMenu.borderWidth * 2, true)
{
foreach (var v in tabsAndPages)
{
this.AddMenuTab(v.Key, v.Value.clone());
}
this.changeTab(startingTab);
}
/// <summary>More modular menu to only have a subset of buttons and pages.</summary>
public ModularGameMenu(string startingTab, Dictionary<Button, IClickableMenuExtended> tabsAndPages)
: base(Game1.viewport.Width / 2 - (800 + IClickableMenu.borderWidth * 2) / 2, Game1.viewport.Height / 2 - (600 + IClickableMenu.borderWidth * 2) / 2, 800 + IClickableMenu.borderWidth * 2, 600 + IClickableMenu.borderWidth * 2, true)
{
foreach (var v in tabsAndPages)
{
this.AddMenuTab(v.Key, v.Value.clone());
}
this.changeTab(this.getTabIndexFromName(startingTab));
}
public int getTabIndexFromName(string tabLabel)
{
for (int i = 0; i < this.menuTabsAndPages.Count; i++)
{
var ok = this.menuTabsAndPages.ElementAt(i);
if (ok.Key.label == tabLabel)
{
return i;
}
}
return 0; //If I can't find it just do a default.
}
public override void snapToDefaultClickableComponent()
{
/*
if (this.currentTab < this.pages.Count)
this.pages[this.currentTab].snapToDefaultClickableComponent();
if (this.junimoNoteIcon == null || this.currentTab >= this.pages.Count || this.pages[this.currentTab].allClickableComponents.Contains((ClickableComponent)this.junimoNoteIcon))
return;
this.pages[this.currentTab].allClickableComponents.Add((ClickableComponent)this.junimoNoteIcon);
*/
this.currentMenu.snapToDefaultClickableComponent();
}
public override void receiveGamePadButton(Buttons b)
{
base.receiveGamePadButton(b);
/*
switch (b)
{
case Buttons.Back:
if (this.currentTab != 0)
break;
this.pages[this.currentTab].receiveGamePadButton(b);
break;
case Buttons.RightTrigger:
if (this.currentTab == 3)
{
Game1.activeClickableMenu = (IClickableMenu)new GameMenu(4, -1);
break;
}
if (this.currentTab >= 7 || !this.pages[this.currentTab].readyToClose())
break;
this.changeTab(this.currentTab + 1);
break;
case Buttons.LeftTrigger:
if (this.currentTab == 3)
{
Game1.activeClickableMenu = (IClickableMenu)new GameMenu(2, -1);
break;
}
if (this.currentTab <= 0 || !this.pages[this.currentTab].readyToClose())
break;
this.changeTab(this.currentTab - 1);
break;
}
*/
this.currentMenu.receiveGamePadButton(b);
}
public override void receiveLeftClick(int x, int y, bool playSound = true)
{
base.receiveLeftClick(x, y, playSound);
//click the menu and stuff here I guess.
Dictionary<Button, IClickableMenuExtended> subTabs = new Dictionary<Button, IClickableMenuExtended>();
for (int i = this.currentPageIndex * tabsPerPage; i < (this.currentPageIndex + 1) * tabsPerPage; i++)
{
if (i >= this.menuTabsAndPages.Count)
break;
var pair = this.menuTabsAndPages.ElementAt(i);
subTabs.Add(pair.Key, pair.Value);
}
foreach (var tab in subTabs)
{
if (tab.Key.containsPoint(x, y))
{
ModCore.ModMonitor.Log(tab.Key.label);
//this.hoverText = tab.Key.label;
this.changeTab(tab.Key, tab.Value);
return;
}
}
//Check for submenu leftclick
this.currentMenu.receiveLeftClick(x, y, playSound);
}
public override void receiveRightClick(int x, int y, bool playSound = true)
{
//base.receiveLeftClick(x, y, playSound);
//click the menu and stuff here I guess.
//Check for submenu right
this.currentMenu.receiveRightClick(x, y);
}
public override void receiveScrollWheelAction(int direction)
{
base.receiveScrollWheelAction(direction);
//this.pages[this.currentTab].receiveScrollWheelAction(direction);
//check for submenu scroll action.
this.currentMenu.receiveScrollWheelAction(direction);
}
public override void performHoverAction(int x, int y)
{
base.performHoverAction(x, y);
this.hoverText = "";
this.currentMenu.performHoverAction(x, y);
//this.pages[this.currentTab].performHoverAction(x, y);
Dictionary<Button, IClickableMenuExtended> subTabs = new Dictionary<Button, IClickableMenuExtended>();
for (int i = this.currentPageIndex * tabsPerPage; i < (this.currentPageIndex + 1) * tabsPerPage; i++)
{
if (i >= this.menuTabsAndPages.Count)
break;
var pair = this.menuTabsAndPages.ElementAt(i);
subTabs.Add(pair.Key, pair.Value);
}
foreach (var tab in subTabs)
{
if (tab.Key.containsPoint(x, y))
{
this.hoverText = tab.Key.label;
return;
}
}
}
public override void releaseLeftClick(int x, int y)
{
base.releaseLeftClick(x, y);
//this.pages[this.currentTab].releaseLeftClick(x, y);
this.currentMenu.releaseLeftClick(x, y);
}
public void pageBack()
{
if (this.currentPageIndex != 0)
this.currentPageIndex--;
}
public void pageForward()
{
if (this.currentPageIndex < this.getNumberOfPages())
this.currentPageIndex++;
}
public override void leftClickHeld(int x, int y)
{
base.leftClickHeld(x, y);
//this.pages[this.currentTab].leftClickHeld(x, y);
this.currentMenu.leftClickHeld(x, y);
}
public override bool readyToClose()
{
if (!GameMenu.forcePreventClose)
return this.currentMenu.readyToClose();
return false;
}
public void changeTab(int which)
{
this.currentPageIndex = which % tabsPerPage;
this.currentButton = this.menuTabsAndPages.ElementAt(which).Key;
this.currentMenu = this.menuTabsAndPages.ElementAt(which).Value;
}
public void changeTab(Button b, IClickableMenuExtended menu)
{
this.currentButton = b;
this.currentMenu = menu;
}
public void setTabNeighborsForCurrentPage() { }
public override void draw(SpriteBatch b)
{
if (!this.invisible)
{
if (!Game1.options.showMenuBackground)
b.Draw(Game1.fadeToBlackRect, Game1.graphics.GraphicsDevice.Viewport.Bounds, Color.Black * 0.4f);
//Game1.drawDialogueBox(this.xPositionOnScreen, this.yPositionOnScreen, currentMenu.width, currentMenu.height, false, true, (string)null, false);
//this.pages[this.currentTab].draw(b);
this.drawDialogueBoxBackground();
b.End();
b.Begin(SpriteSortMode.FrontToBack, BlendState.NonPremultiplied, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null);
Dictionary<Button, IClickableMenuExtended> subTabs = new Dictionary<Button, IClickableMenuExtended>();
for (int i = this.currentPageIndex * tabsPerPage; i < (this.currentPageIndex + 1) * tabsPerPage; i++)
{
if (i >= this.menuTabsAndPages.Count)
break;
var pair = this.menuTabsAndPages.ElementAt(i);
subTabs.Add(pair.Key, pair.Value);
}
foreach (var tab in subTabs)
{
if (tab.Key.visible)
{
if (tab.Key == this.currentButton)
{
tab.Key.draw(b, Color.White, new Vector2(0, 0));
continue;
}
tab.Key.draw(b);
}
}
this.currentMenu.draw(b);
if (Game1.options.hardwareCursor)
return;
b.Draw(Game1.mouseCursors, new Vector2((float)Game1.getOldMouseX(), (float)Game1.getOldMouseY()), new Rectangle?(Game1.getSourceRectForStandardTileSheet(Game1.mouseCursors, Game1.options.gamepadControls ? 44 : 0, 16, 16)), Color.White, 0.0f, Vector2.Zero, (float)(4.0 + (double)Game1.dialogueButtonScale / 150.0), SpriteEffects.None, 1f);
}
}
public override bool areGamePadControlsImplemented()
{
return false;
}
public override void receiveKeyPress(Keys key)
{
if (Game1.options.menuButton.Contains(new InputButton(key)) && this.readyToClose())
{
Game1.exitActiveMenu();
Game1.playSound("bigDeSelect");
}
//this.pages[this.currentTab].receiveKeyPress(key);
this.currentMenu.receiveKeyPress(key);
}
public override void emergencyShutDown()
{
base.emergencyShutDown();
this.currentMenu.emergencyShutDown();
}
}
}