Ui-Info-Suite/SDVModTest/Options/ModOptionsPage.cs

361 lines
14 KiB
C#

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using StardewValley;
using StardewValley.Menus;
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Graphics;
using StardewModdingAPI.Events;
namespace UIInfoSuite.Options
{
public class ModOptionsPage : IClickableMenu
{
private const int Width = 800;
private List<ClickableComponent> _optionSlots = new List<ClickableComponent>();
private List<ModOptionsElement> _options;
private String _hoverText;
private int _optionsSlotHeld;
private int _currentItemIndex;
private bool _isScrolling;
private ClickableTextureComponent _upArrow;
private ClickableTextureComponent _downArrow;
private ClickableTextureComponent _scrollBar;
private Rectangle _scrollBarRunner;
public ModOptionsPage(List<ModOptionsElement> options, IModEvents events)
: base(Game1.activeClickableMenu.xPositionOnScreen, Game1.activeClickableMenu.yPositionOnScreen + 10, Width, Game1.activeClickableMenu.height)
{
_options = options;
_upArrow = new ClickableTextureComponent(
new Rectangle(
xPositionOnScreen + width + Game1.tileSize / 4,
yPositionOnScreen + Game1.tileSize,
11 * Game1.pixelZoom,
12 * Game1.pixelZoom),
Game1.mouseCursors,
new Rectangle(421, 459, 11, 12),
Game1.pixelZoom);
_downArrow = new ClickableTextureComponent(
new Rectangle(
_upArrow.bounds.X,
yPositionOnScreen + height - Game1.tileSize,
_upArrow.bounds.Width,
_upArrow.bounds.Height),
Game1.mouseCursors,
new Rectangle(421, 472, 11, 12),
Game1.pixelZoom);
_scrollBar = new ClickableTextureComponent(
new Rectangle(
_upArrow.bounds.X + Game1.pixelZoom * 3,
_upArrow.bounds.Y + _upArrow.bounds.Height + Game1.pixelZoom,
6 * Game1.pixelZoom,
10 * Game1.pixelZoom),
Game1.mouseCursors,
new Rectangle(435, 463, 6, 10),
Game1.pixelZoom);
_scrollBarRunner = new Rectangle(_scrollBar.bounds.X,
_scrollBar.bounds.Y,
_scrollBar.bounds.Width,
height - Game1.tileSize * 2 - _upArrow.bounds.Height - Game1.pixelZoom * 2);
for (int i = 0; i < 7; ++i)
_optionSlots.Add(new ClickableComponent(
new Rectangle(
xPositionOnScreen + Game1.tileSize / 4,
yPositionOnScreen + Game1.tileSize * 5 / 4 + Game1.pixelZoom + i * (height - Game1.tileSize * 2) / 7,
width - Game1.tileSize / 2,
(height - Game1.tileSize * 2) / 7 + Game1.pixelZoom),
i.ToString()));
events.Display.MenuChanged += OnMenuChanged;
}
/// <summary>Raised after a game menu is opened, closed, or replaced.</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
private void OnMenuChanged(object sender, MenuChangedEventArgs e)
{
if (e.NewMenu is GameMenu)
{
xPositionOnScreen = Game1.activeClickableMenu.xPositionOnScreen;
yPositionOnScreen = Game1.activeClickableMenu.yPositionOnScreen + 10;
height = Game1.activeClickableMenu.height;
for (int i = 0; i < _optionSlots.Count; ++i)
{
var next = _optionSlots[i];
next.bounds.X = xPositionOnScreen + Game1.tileSize / 4;
next.bounds.Y = yPositionOnScreen + Game1.tileSize * 5 / 4 + Game1.pixelZoom + i * (height - Game1.tileSize * 2) / 7;
next.bounds.Width = width - Game1.tileSize / 2;
next.bounds.Height = (height - Game1.tileSize * 2) / 7 + Game1.pixelZoom;
}
_upArrow.bounds.X = xPositionOnScreen + width + Game1.tileSize / 4;
_upArrow.bounds.Y = yPositionOnScreen + Game1.tileSize;
_upArrow.bounds.Width = 11 * Game1.pixelZoom;
_upArrow.bounds.Height = 12 * Game1.pixelZoom;
_downArrow.bounds.X = _upArrow.bounds.X;
_downArrow.bounds.Y = yPositionOnScreen + height - Game1.tileSize;
_downArrow.bounds.Width = _upArrow.bounds.Width;
_downArrow.bounds.Height = _upArrow.bounds.Height;
_scrollBar.bounds.X = _upArrow.bounds.X + Game1.pixelZoom * 3;
_scrollBar.bounds.Y = _upArrow.bounds.Y + _upArrow.bounds.Height + Game1.pixelZoom;
_scrollBar.bounds.Width = 6 * Game1.pixelZoom;
_scrollBar.bounds.Height = 10 * Game1.pixelZoom;
_scrollBarRunner.X = _scrollBar.bounds.X;
_scrollBarRunner.Y = _scrollBar.bounds.Y;
_scrollBarRunner.Width = _scrollBar.bounds.Width;
_scrollBarRunner.Height = height - Game1.tileSize * 2 - _upArrow.bounds.Height - Game1.pixelZoom * 2;
}
}
private void SetScrollBarToCurrentItem()
{
if (_options.Count > 0)
{
_scrollBar.bounds.Y = _scrollBarRunner.Height / Math.Max(1, _options.Count - 7 + 1) * _currentItemIndex + _upArrow.bounds.Bottom + Game1.pixelZoom;
if (_currentItemIndex == _options.Count - 7)
{
_scrollBar.bounds.Y = _downArrow.bounds.Y - _scrollBar.bounds.Height - Game1.pixelZoom;
}
}
}
public override void leftClickHeld(int x, int y)
{
if (!GameMenu.forcePreventClose)
{
base.leftClickHeld(x, y);
if (_isScrolling)
{
int yBefore = _scrollBar.bounds.Y;
_scrollBar.bounds.Y = Math.Min(
yPositionOnScreen + height - Game1.tileSize - Game1.pixelZoom * 3 - _scrollBar.bounds.Height,
Math.Max(
y,
yPositionOnScreen + _upArrow.bounds.Height + Game1.pixelZoom * 5));
_currentItemIndex = Math.Min(
_options.Count - 7,
Math.Max(
0,
_options.Count * (y - _scrollBarRunner.Y) / _scrollBarRunner.Height));
SetScrollBarToCurrentItem();
if (yBefore != _scrollBar.bounds.Y)
Game1.playSound("shiny4");
}
else if (_optionsSlotHeld > -1 && _optionsSlotHeld + _currentItemIndex < _options.Count)
{
_options[_currentItemIndex + _optionsSlotHeld].LeftClickHeld(
x - _optionSlots[_optionsSlotHeld].bounds.X,
y - _optionSlots[_optionsSlotHeld].bounds.Y);
}
}
}
public override void receiveKeyPress(Keys key)
{
if (_optionsSlotHeld > -1 &&
_optionsSlotHeld + _currentItemIndex < _options.Count)
{
_options[_currentItemIndex + _optionsSlotHeld].ReceiveKeyPress(key);
}
}
public override void receiveScrollWheelAction(int direction)
{
if (!GameMenu.forcePreventClose)
{
base.receiveScrollWheelAction(direction);
if (direction > 0 && _currentItemIndex > 0)
{
UpArrowPressed();
Game1.playSound("shiny4");
}
else if (direction < 0 && _currentItemIndex < Math.Max(0, _options.Count - 7))
{
DownArrowPressed();
Game1.playSound("shiny4");
}
}
}
public override void releaseLeftClick(int x, int y)
{
if (!GameMenu.forcePreventClose)
{
base.releaseLeftClick(x, y);
if (_optionsSlotHeld > -1 && _optionsSlotHeld + _currentItemIndex < _options.Count)
{
ClickableComponent optionSlot = _optionSlots[_optionsSlotHeld];
_options[_currentItemIndex + _optionsSlotHeld].LeftClickReleased(x - optionSlot.bounds.X, y - optionSlot.bounds.Y);
}
_optionsSlotHeld = -1;
_isScrolling = false;
}
}
private void DownArrowPressed()
{
_downArrow.scale = _downArrow.baseScale;
++_currentItemIndex;
SetScrollBarToCurrentItem();
}
private void UpArrowPressed()
{
_upArrow.scale = _upArrow.baseScale;
--_currentItemIndex;
SetScrollBarToCurrentItem();
}
public override void receiveLeftClick(int x, int y, bool playSound = true)
{
if (!GameMenu.forcePreventClose)
{
if (_downArrow.containsPoint(x, y) && _currentItemIndex < Math.Max(0, _options.Count - 7))
{
DownArrowPressed();
Game1.playSound("shwip");
}
else if (_upArrow.containsPoint(x, y) && _currentItemIndex > 0)
{
UpArrowPressed();
Game1.playSound("shwip");
}
else if (_scrollBar.containsPoint(x, y))
{
_isScrolling = true;
}
else if (!_downArrow.containsPoint(x, y) &&
x > xPositionOnScreen + width &&
x < xPositionOnScreen + width + Game1.tileSize * 2 &&
y > yPositionOnScreen &&
y < yPositionOnScreen + height)
{
_isScrolling = true;
base.leftClickHeld(x, y);
base.releaseLeftClick(x, y);
}
_currentItemIndex = Math.Max(0, Math.Min(_options.Count - 7, _currentItemIndex));
for (int i = 0; i < _optionSlots.Count; ++i)
{
if (_optionSlots[i].bounds.Contains(x, y) &&
_currentItemIndex + i < _options.Count &&
_options[_currentItemIndex + i].Bounds.Contains(x - _optionSlots[i].bounds.X, y - _optionSlots[i].bounds.Y))
{
_options[_currentItemIndex + i].ReceiveLeftClick(
x - _optionSlots[i].bounds.X,
y - _optionSlots[i].bounds.Y);
_optionsSlotHeld = i;
break;
}
}
}
}
public override void receiveRightClick(int x, int y, bool playSound = true)
{
}
public override void receiveGamePadButton(Buttons b)
{
if (b == Buttons.A)
{
receiveLeftClick(Game1.getMouseX(), Game1.getMouseY());
}
}
public override void performHoverAction(int x, int y)
{
if (!GameMenu.forcePreventClose)
{
_hoverText = "";
_upArrow.tryHover(x, y);
_downArrow.tryHover(x, y);
_scrollBar.tryHover(x, y);
}
}
public override void draw(SpriteBatch batch)
{
Game1.drawDialogueBox(xPositionOnScreen, yPositionOnScreen - 10, width, height, false, true);
batch.End();
batch.Begin(SpriteSortMode.FrontToBack, BlendState.NonPremultiplied, SamplerState.PointClamp, null, null);
for (int i = 0; i < _optionSlots.Count; ++i)
{
if (_currentItemIndex >= 0 &&
_currentItemIndex + i < _options.Count)
{
_options[_currentItemIndex + i].Draw(
batch,
_optionSlots[i].bounds.X,
_optionSlots[i].bounds.Y);
}
}
batch.End();
batch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
if (!GameMenu.forcePreventClose)
{
_upArrow.draw(batch);
_downArrow.draw(batch);
if (_options.Count > 7)
{
IClickableMenu.drawTextureBox(
batch,
Game1.mouseCursors,
new Rectangle(403, 383, 6, 6),
_scrollBarRunner.X,
_scrollBarRunner.Y,
_scrollBarRunner.Width,
_scrollBarRunner.Height,
Color.White,
Game1.pixelZoom,
false);
_scrollBar.draw(batch);
}
}
if (_hoverText != "")
IClickableMenu.drawHoverText(batch, _hoverText, Game1.smallFont);
//if (Game1.options.hardwareCursor)
//{
// Game1.spriteBatch.Draw(
// Game1.mouseCursors,
// new Vector2(
// Game1.getMouseX(),
// Game1.getMouseY()),
// new Rectangle?(
// Game1.getSourceRectForStandardTileSheet(
// Game1.mouseCursors,
// Game1.mouseCursor,
// 16,
// 16)),
// Color.White,
// 0.0f,
// Vector2.Zero,
// (float)(Game1.pixelZoom + (Game1.dialogueButtonScale / 150.0)),
// SpriteEffects.None,
// 1f);
//}
}
}
}