| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778 |
- //-----------------------------------------------------------------------------
- // SettingsScreen.cs
- //
- // Settings screen with custom layout for adjusting game options
- //-----------------------------------------------------------------------------
- using System;
- using System.Collections.Generic;
- using GameStateManagement;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Graphics;
- using Microsoft.Xna.Framework.Input;
- using Microsoft.Xna.Framework.Input.Touch;
- using Microsoft.Xna.Framework.Content;
- using System.IO;
- using CardsFramework;
- namespace Blackjack
- {
- class SettingsScreen : GameScreen
- {
- private Texture2D background;
- private Texture2D cardBackTexture;
- private Texture2D buttonRegularTexture;
- private Texture2D buttonPressedTexture;
- // Fonts are accessed directly from ScreenManager to ensure we always use current font
- private GameSettings settings;
- private Rectangle safeArea;
- // Card preview
- private Vector2 cardPreviewPosition;
- private Vector2 cardSize;
- // Setting item areas
- private List<SettingItem> settingItems = new List<SettingItem>();
- private int selectedIndex = -1;
- private int hoveredIndex = -1;
- private int pressedButtonIndex = -1; // Which button is being pressed (-1 for none, 0 for left, 1 for right)
- // Pagination
- private int currentPage = 0;
- private const int TotalPages = 2;
- private Rectangle nextButtonBounds;
- private Rectangle prevButtonBounds;
- private bool isNextButtonPressed = false;
- private bool isPrevButtonPressed = false;
- private Rectangle backButtonBounds;
- private bool isBackButtonPressed = false;
- private bool isMouseDown = false;
- private float itemSpacing;
- private float groupSpacing;
- private float leftMargin;
- private float buttonSize;
- private float rightButtonMargin;
- private float buttonSpacing;
- public SettingsScreen()
- {
- // Settings screen needs Tap gestures for mobile
- EnabledGestures = GestureType.Tap;
-
- TransitionOnTime = TimeSpan.FromSeconds(0.5);
- TransitionOffTime = TimeSpan.FromSeconds(0.5);
- settings = GameSettings.Instance;
- }
- public override void LoadContent()
- {
- ContentManager content = ScreenManager.Game.Content;
- background = content.Load<Texture2D>("Images/UI/table");
- // Fonts are accessed directly from ScreenManager properties (no caching)
- buttonRegularTexture = content.Load<Texture2D>("Images/ButtonRegular");
- buttonPressedTexture = content.Load<Texture2D>("Images/ButtonPressed");
- // Load current theme card back using invariant theme value
- string themeCardBack = $"CardBack_{settings.Theme}";
- cardBackTexture = content.Load<Texture2D>($"Images/Cards/{themeCardBack}");
- safeArea = ScreenManager.SafeArea;
- // Calculate proportional spacing and sizes based on screen height
- float heightScale = safeArea.Height / 720f; // Scale based on 720p baseline
- itemSpacing = 45f * heightScale;
- groupSpacing = 60f * heightScale;
- leftMargin = 80f * heightScale;
- buttonSize = 32f * heightScale;
- rightButtonMargin = 10f * heightScale;
- buttonSpacing = 168f * heightScale; // Space between left and right buttons
- // Calculate card preview position and size (proportional to screen)
- cardSize = new Vector2(80 * heightScale, 120 * heightScale);
- cardPreviewPosition = new Vector2(
- safeArea.Center.X - cardSize.X / 2,
- safeArea.Top + 50 * heightScale
- );
- BuildSettingItems();
- base.LoadContent();
- }
- /// <summary>
- /// Reloads fonts when language changes between CJK and non-CJK languages.
- /// </summary>
- public void ReloadFonts(bool useCJKFont)
- {
- // No need to cache fonts - they're accessed directly from ScreenManager
- // Don't rebuild items here - will be done after language is set to avoid
- // measuring text in new language with old fonts
- }
- private void BuildSettingItems()
- {
- settingItems.Clear();
- float yPos = cardPreviewPosition.Y + cardSize.Y + 20; // Start below card preview
- if (currentPage == 0)
- {
- // Page 1: DISPLAY and AUDIO
- AddHeader(Resources.SettingsDisplay, ref yPos);
- AddCycleSetting(Resources.SettingsLanguage, GetLanguageDisplay,
- CycleToPreviousLanguage,
- CycleToNextLanguage,
- null, ref yPos);
- AddCycleSetting(Resources.SettingsCardBackTheme, GetThemeDisplay,
- () => settings.Theme = settings.Theme == "Red" ? "Blue" : "Red",
- () => settings.Theme = settings.Theme == "Red" ? "Blue" : "Red",
- () =>
- {
- // Reload card back texture using invariant theme value
- string themeCardBack = $"CardBack_{settings.Theme}";
- cardBackTexture = ScreenManager.Game.Content.Load<Texture2D>($"Images/Cards/{themeCardBack}");
- MainMenuScreen.Theme = settings.Theme;
- },
- ref yPos);
- AddCycleSetting(Resources.SettingsCurrency, () => settings.Currency,
- CycleToPreviousCurrency,
- CycleToNextCurrency,
- null, ref yPos);
- yPos += groupSpacing - itemSpacing; // Extra space before next group
- // AUDIO section
- AddHeader(Resources.SettingsAudio, ref yPos);
- AddSliderSetting(Resources.SettingsSoundVolume, () => settings.SoundVolume,
- (v) => settings.SoundVolume = v, ref yPos);
- AddSliderSetting(Resources.SettingsMusicVolume, () => settings.MusicVolume,
- (v) => settings.MusicVolume = v, ref yPos);
- }
- else if (currentPage == 1)
- {
- // Page 2: GAMEPLAY and NPC Players
- AddHeader(Resources.SettingsGameplay, ref yPos);
- AddCycleSetting(Resources.SettingsAnimationSpeed, () => settings.AnimationSpeed.ToString(),
- () =>
- {
- settings.AnimationSpeed = settings.AnimationSpeed switch
- {
- AnimationSpeed.Fast => AnimationSpeed.Normal,
- AnimationSpeed.Normal => AnimationSpeed.Slow,
- _ => AnimationSpeed.Fast
- };
- },
- () =>
- {
- settings.AnimationSpeed = settings.AnimationSpeed switch
- {
- AnimationSpeed.Slow => AnimationSpeed.Normal,
- AnimationSpeed.Normal => AnimationSpeed.Fast,
- _ => AnimationSpeed.Slow
- };
- },
- null, ref yPos);
- AddCheckboxSetting(Resources.SettingsAutoStandOn21, () => settings.AutoStandOn21,
- (v) => settings.AutoStandOn21 = v, ref yPos);
- AddCheckboxSetting(Resources.SettingsShowCardCount, () => settings.ShowCardCount,
- (v) => settings.ShowCardCount = v, ref yPos);
- AddCheckboxSetting(Resources.SettingsPersistWinnings, () => settings.PersistWinnings,
- (v) => settings.PersistWinnings = v, ref yPos);
- yPos += groupSpacing - itemSpacing; // Extra space before next group
- // NPC Players section
- AddHeader(Resources.SettingsNPCPlayers, ref yPos);
- AddCounterSetting(Resources.SettingsMaxNPCPlayers, () => settings.MaxNPCPlayers, 0, GameSettings.GetPlatformMaxNPCPlayers(),
- (v) => settings.MaxNPCPlayers = (byte)v, ref yPos);
- AddCheckboxSetting(Resources.SettingsFillEmptySlots, () => settings.FillEmptySlotsWithNPC,
- (v) => settings.FillEmptySlotsWithNPC = v, ref yPos);
- }
- // Calculate navigation button bounds at bottom (proportional to screen)
- float heightScale = safeArea.Height / 720f;
- int navButtonY = safeArea.Bottom - (int)(60 * heightScale);
- int navButtonHeight = (int)(40 * heightScale);
- // Calculate button widths based on text size with padding
- Vector2 prevTextSize = ScreenManager.RegularFont.MeasureString(Resources.Previous);
- Vector2 nextTextSize = ScreenManager.RegularFont.MeasureString(Resources.Next);
- int prevButtonWidth = (int)(prevTextSize.X + 40 * heightScale);
- int nextButtonWidth = (int)(nextTextSize.X + 40 * heightScale);
- prevButtonBounds = new Rectangle(safeArea.Left + (int)(100 * heightScale), navButtonY, prevButtonWidth, navButtonHeight);
- nextButtonBounds = new Rectangle(safeArea.Right - nextButtonWidth - (int)(100 * heightScale), navButtonY, nextButtonWidth, navButtonHeight);
- // Calculate back button bounds in top-left corner
- int backButtonSize = (int)(50 * heightScale);
- int backButtonPadding = (int)(20 * heightScale);
- backButtonBounds = new Rectangle(
- safeArea.Left + backButtonPadding,
- safeArea.Top + backButtonPadding,
- backButtonSize,
- backButtonSize);
- }
- private string GetLanguageDisplay()
- {
- // Language names are already stored in native format
- return settings.Language;
- }
- private string GetThemeDisplay()
- {
- // Return the localized theme name based on current language
- // Theme is stored as invariant "Red" or "Blue" but displayed in user's language
- return settings.Theme == "Red" ? Resources.CardBackColorRed : Resources.CardBackColorBlue;
- }
- private void CycleToNextLanguage()
- {
- // Determine next language
- string nextLanguage = settings.Language switch
- {
- "English" => "Français",
- "Français" => "Español",
- "Español" => "Italiano",
- "Italiano" => "Русский",
- "Русский" => "日本語",
- "日本語" => "中文",
- "中文" => "English",
- _ => "English"
- };
- // Phase 1: Reload fonts BEFORE changing language
- ScreenManager.ReloadFontForLanguage(nextLanguage);
- // Phase 2: Set the language (this will change CurrentUICulture)
- settings.Language = nextLanguage;
- // Phase 3: Refresh all screens now that language and fonts are both updated
- BuildSettingItems();
- ScreenManager.RefreshScreensAfterLanguageChange();
- }
- private void CycleToPreviousLanguage()
- {
- // Determine previous language
- string previousLanguage = settings.Language switch
- {
- "English" => "中文",
- "中文" => "日本語",
- "日本語" => "Русский",
- "Русский" => "Italiano",
- "Italiano" => "Español",
- "Español" => "Français",
- "Français" => "English",
- _ => "中文" // Default to last active language
- };
- // Phase 1: Reload fonts BEFORE changing language
- ScreenManager.ReloadFontForLanguage(previousLanguage);
- // Phase 2: Set the language (this will change CurrentUICulture)
- settings.Language = previousLanguage;
- // Phase 3: Refresh all screens now that language and fonts are both updated
- BuildSettingItems();
- ScreenManager.RefreshScreensAfterLanguageChange();
- }
- private void CycleToNextCurrency()
- {
- settings.Currency = settings.Currency switch
- {
- "$" => "€",
- "€" => "£",
- "£" => "¥",
- "¥" => "R",
- "R" => "$",
- _ => "$"
- };
- GameSettings.Save();
- }
- private void CycleToPreviousCurrency()
- {
- settings.Currency = settings.Currency switch
- {
- "$" => "R",
- "R" => "¥",
- "¥" => "£",
- "£" => "€",
- "€" => "$",
- _ => "$"
- };
- GameSettings.Save();
- }
- private void AddHeader(string text, ref float yPos)
- {
- settingItems.Add(new SettingItem
- {
- Type = SettingType.Header,
- Label = text,
- Bounds = new Rectangle((int)leftMargin, (int)yPos, safeArea.Width - (int)leftMargin * 2, (int)(40 * (safeArea.Height / 720f)))
- });
- yPos += itemSpacing;
- }
- private void AddCounterSetting(string label, Func<int> getValue, int min, int max,
- Action<int> setValue, ref float yPos)
- {
- settingItems.Add(new SettingItem
- {
- Type = SettingType.Counter,
- Label = label,
- GetValue = () => getValue().ToString(),
- OnDecrease = () =>
- {
- int val = getValue() - 1;
- if (val < min) val = max;
- setValue(val);
- GameSettings.Save();
- },
- OnIncrease = () =>
- {
- int val = getValue() + 1;
- if (val > max) val = min;
- setValue(val);
- GameSettings.Save();
- },
- Bounds = new Rectangle((int)leftMargin, (int)yPos, safeArea.Width - (int)leftMargin * 2, (int)(40 * (safeArea.Height / 720f)))
- });
- yPos += itemSpacing;
- }
- private void AddSliderSetting(string label, Func<float> getValue, Action<float> setValue, ref float yPos)
- {
- settingItems.Add(new SettingItem
- {
- Type = SettingType.Slider,
- Label = label,
- GetValue = () => $"{(int)(getValue() * 100)}%",
- OnDecrease = () =>
- {
- float val = getValue() - 0.1f;
- if (val < 0) val = 1.0f;
- setValue(val);
- GameSettings.Save();
- },
- OnIncrease = () =>
- {
- float val = getValue() + 0.1f;
- if (val > 1.0f) val = 0f;
- setValue(val);
- GameSettings.Save();
- },
- Bounds = new Rectangle((int)leftMargin, (int)yPos, safeArea.Width - (int)leftMargin * 2, (int)(40 * (safeArea.Height / 720f)))
- });
- yPos += itemSpacing;
- }
- private void AddCheckboxSetting(string label, Func<bool> getValue, Action<bool> setValue, ref float yPos)
- {
- settingItems.Add(new SettingItem
- {
- Type = SettingType.Checkbox,
- Label = label,
- GetValue = () => getValue() ? "[X]" : "[ ]",
- OnClick = () =>
- {
- setValue(!getValue());
- GameSettings.Save();
- },
- Bounds = new Rectangle((int)leftMargin, (int)yPos, safeArea.Width - (int)leftMargin * 2, (int)(40 * (safeArea.Height / 720f)))
- });
- yPos += itemSpacing;
- }
- private void AddCycleSetting(string label, Func<string> getValue, Action onPrevious, Action onNext,
- Action onChange, ref float yPos)
- {
- settingItems.Add(new SettingItem
- {
- Type = SettingType.Cycle,
- Label = label,
- GetValue = getValue,
- OnDecrease = () =>
- {
- onPrevious();
- onChange?.Invoke();
- GameSettings.Save();
- },
- OnIncrease = () =>
- {
- onNext();
- onChange?.Invoke();
- GameSettings.Save();
- },
- Bounds = new Rectangle((int)leftMargin, (int)yPos, safeArea.Width - (int)leftMargin * 2, (int)(40 * (safeArea.Height / 720f)))
- });
- yPos += itemSpacing;
- }
- public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
- {
- base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
- }
- /// <summary>
- /// Responds to user input.
- /// </summary>
- public override void HandleInput(InputState inputState)
- {
- // Cancel the settings screen if the user presses the back button
- PlayerIndex player;
- if (inputState.IsNewButtonPress(Buttons.Back, ControllingPlayer, out player))
- {
- ExitScreen();
- return;
- }
- // Check for escape key
- if (inputState.IsNewKeyPress(Keys.Escape, ControllingPlayer, out player))
- {
- ExitScreen();
- return;
- }
- // Get transformed cursor position (handles scaling/letterboxing on mobile)
- Vector2 cursorPos = inputState.CurrentCursorLocation;
- Point mousePos = new Point((int)cursorPos.X, (int)cursorPos.Y);
- // Track button press state
- pressedButtonIndex = -1;
- isNextButtonPressed = false;
- isPrevButtonPressed = false;
- isBackButtonPressed = false;
- if (UIUtility.IsDesktop)
- {
- // Handle mouse input - detect click (press + release)
- if (inputState.CurrentMouseState.LeftButton == ButtonState.Released)
- {
- if (isMouseDown)
- {
- isMouseDown = false;
- HandleSettingItemClick(mousePos);
- }
- }
- else if (inputState.CurrentMouseState.LeftButton == ButtonState.Pressed)
- {
- isMouseDown = true;
- // Track hover on press
- TrackHoverState(mousePos);
- }
- }
- else if (UIUtility.IsMobile)
- {
- // Handle touch input with gestures (like MenuScreen does)
- foreach (GestureSample gesture in inputState.Gestures)
- {
- if (gesture.GestureType == GestureType.Tap)
- {
- HandleSettingItemClick(mousePos);
- }
- }
- }
- // Track hover state for visual feedback on desktop
- if (UIUtility.IsDesktop && inputState.CurrentMouseState.LeftButton == ButtonState.Released)
- {
- TrackHoverState(mousePos);
- }
- }
- private void HandleSettingItemClick(Point clickLocation)
- {
- // Check back button
- if (backButtonBounds.Contains(clickLocation))
- {
- isBackButtonPressed = true;
- AudioManager.PlaySound("menu_select");
- ExitScreen();
- return;
- }
- // Check navigation buttons
- if (currentPage < TotalPages - 1 && nextButtonBounds.Contains(clickLocation))
- {
- isNextButtonPressed = true;
- currentPage++;
- BuildSettingItems();
- AudioManager.PlaySound("menu_select");
- return;
- }
- else if (currentPage > 0 && prevButtonBounds.Contains(clickLocation))
- {
- isPrevButtonPressed = true;
- currentPage--;
- BuildSettingItems();
- AudioManager.PlaySound("menu_select");
- return;
- }
- // Check setting items
- for (int i = 0; i < settingItems.Count; i++)
- {
- SettingItem item = settingItems[i];
- if (item.Type == SettingType.Header) continue;
- if (item.Bounds.Contains(clickLocation))
- {
- // Button bounds
- Rectangle leftButton = GetLeftButtonBounds(item.Bounds);
- Rectangle rightButton = GetRightButtonBounds(item.Bounds);
- if (item.Type == SettingType.Checkbox)
- {
- // Get checkbox bounds (centered in value column)
- Rectangle checkboxBounds = GetCheckboxButtonBounds(item.Bounds);
- if (checkboxBounds.Contains(clickLocation))
- {
- item.OnClick?.Invoke();
- AudioManager.PlaySound("menu_select");
- }
- }
- else if (leftButton.Contains(clickLocation))
- {
- item.OnDecrease?.Invoke();
- AudioManager.PlaySound("menu_select");
- pressedButtonIndex = i * 2; // Even indices for left buttons
- }
- else if (rightButton.Contains(clickLocation))
- {
- item.OnIncrease?.Invoke();
- AudioManager.PlaySound("menu_select");
- pressedButtonIndex = i * 2 + 1; // Odd indices for right buttons
- }
- break;
- }
- }
- }
- private void TrackHoverState(Point mousePos)
- {
- // Track hover state for visual feedback
- hoveredIndex = -1;
- for (int i = 0; i < settingItems.Count; i++)
- {
- if (settingItems[i].Type != SettingType.Header &&
- settingItems[i].Bounds.Contains(mousePos))
- {
- hoveredIndex = i;
- break;
- }
- }
- }
- private Rectangle GetLeftButtonBounds(Rectangle itemBounds)
- {
- return new Rectangle(
- itemBounds.Right - (int)(buttonSpacing + buttonSize + rightButtonMargin),
- itemBounds.Y + (itemBounds.Height - (int)buttonSize) / 2,
- (int)buttonSize, (int)buttonSize);
- }
- private Rectangle GetRightButtonBounds(Rectangle itemBounds)
- {
- return new Rectangle(
- itemBounds.Right - (int)buttonSize - (int)rightButtonMargin,
- itemBounds.Y + (itemBounds.Height - (int)buttonSize) / 2,
- (int)buttonSize, (int)buttonSize);
- }
- private Rectangle GetCheckboxButtonBounds(Rectangle itemBounds)
- {
- // Center in the value column, matching the position where counter values appear
- int leftButtonRight = itemBounds.Right - (int)(buttonSpacing + buttonSize + rightButtonMargin) + (int)buttonSize;
- int rightButtonLeft = itemBounds.Right - (int)buttonSize - (int)rightButtonMargin;
- int centerX = (leftButtonRight + rightButtonLeft) / 2 - (int)buttonSize / 2;
- return new Rectangle(
- centerX,
- itemBounds.Y + (itemBounds.Height - (int)buttonSize) / 2,
- (int)buttonSize, (int)buttonSize);
- }
- public override void Draw(GameTime gameTime)
- {
- SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
- spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, ScreenManager.GlobalTransformation);
- // Draw background
- spriteBatch.Draw(background, safeArea, Color.White * TransitionAlpha);
- // Draw title
- string title = Resources.SettingsTitle;
- Vector2 titleSize = ScreenManager.Font.MeasureString(title);
- Vector2 titlePos = new Vector2(safeArea.Center.X - titleSize.X / 2, safeArea.Top + 10);
- spriteBatch.DrawString(ScreenManager.Font, title, titlePos, Color.White * TransitionAlpha);
- // Draw card preview
- Rectangle cardRect = new Rectangle((int)cardPreviewPosition.X, (int)cardPreviewPosition.Y,
- (int)cardSize.X, (int)cardSize.Y);
- spriteBatch.Draw(cardBackTexture, cardRect, Color.White * TransitionAlpha);
- // Draw all setting items
- for (int i = 0; i < settingItems.Count; i++)
- {
- SettingItem item = settingItems[i];
- Color color = Color.White * TransitionAlpha;
- if (item.Type == SettingType.Header)
- {
- // Draw header with larger font
- Vector2 headerPos = new Vector2(item.Bounds.X, item.Bounds.Y);
- spriteBatch.DrawString(ScreenManager.Font, item.Label, headerPos,
- Color.Gold * TransitionAlpha);
- }
- else
- {
- // Highlight if hovered
- if (i == hoveredIndex)
- {
- spriteBatch.Draw(background, item.Bounds, Color.White * 0.2f * TransitionAlpha);
- }
- // Draw label
- Vector2 labelPos = new Vector2(item.Bounds.X + 10,
- item.Bounds.Y + (item.Bounds.Height - ScreenManager.RegularFont.LineSpacing) / 2);
- spriteBatch.DrawString(ScreenManager.RegularFont, item.Label, labelPos, color);
- // Draw value and controls
- string valueText = item.GetValue?.Invoke() ?? "";
- Vector2 valueSize = ScreenManager.RegularFont.MeasureString(valueText);
- if (item.Type == SettingType.Checkbox)
- {
- // Draw checkbox as a button in the center of the value column
- bool isChecked = item.GetValue?.Invoke() == "[X]";
- Rectangle checkboxBounds = GetCheckboxButtonBounds(item.Bounds);
- Texture2D checkboxTexture = isChecked ? buttonPressedTexture : buttonRegularTexture;
- spriteBatch.Draw(checkboxTexture, checkboxBounds, Color.White * TransitionAlpha);
- // Draw checkmark if checked
- if (isChecked)
- {
- Vector2 checkSize = ScreenManager.RegularFont.MeasureString("X");
- Vector2 checkPos = new Vector2(
- checkboxBounds.X + (checkboxBounds.Width - checkSize.X) / 2,
- checkboxBounds.Y + (checkboxBounds.Height - checkSize.Y) / 2);
- spriteBatch.DrawString(ScreenManager.RegularFont, "X", checkPos, Color.Black * TransitionAlpha);
- }
- }
- else
- {
- // Get button bounds
- Rectangle leftButton = GetLeftButtonBounds(item.Bounds);
- Rectangle rightButton = GetRightButtonBounds(item.Bounds);
- // Draw left button [-]
- bool leftPressed = (pressedButtonIndex == i * 2);
- Texture2D leftTexture = leftPressed ? buttonPressedTexture : buttonRegularTexture;
- spriteBatch.Draw(leftTexture, leftButton, Color.White * TransitionAlpha);
- Vector2 minusSize = ScreenManager.RegularFont.MeasureString("-");
- Vector2 minusPos = new Vector2(
- leftButton.X + (leftButton.Width - minusSize.X) / 2,
- leftButton.Y + (leftButton.Height - minusSize.Y) / 2);
- spriteBatch.DrawString(ScreenManager.RegularFont, "-", minusPos, Color.Black * TransitionAlpha);
- // Draw value in center
- Vector2 valuePos = new Vector2(
- leftButton.Right + (rightButton.Left - leftButton.Right - valueSize.X) / 2,
- item.Bounds.Y + (item.Bounds.Height - ScreenManager.RegularFont.LineSpacing) / 2);
- spriteBatch.DrawString(ScreenManager.RegularFont, valueText, valuePos, color);
- // Draw right button [+]
- bool rightPressed = (pressedButtonIndex == i * 2 + 1);
- Texture2D rightTexture = rightPressed ? buttonPressedTexture : buttonRegularTexture;
- spriteBatch.Draw(rightTexture, rightButton, Color.White * TransitionAlpha);
- Vector2 plusSize = ScreenManager.RegularFont.MeasureString("+");
- Vector2 plusPos = new Vector2(
- rightButton.X + (rightButton.Width - plusSize.X) / 2,
- rightButton.Y + (rightButton.Height - plusSize.Y) / 2);
- spriteBatch.DrawString(ScreenManager.RegularFont, "+", plusPos, Color.Black * TransitionAlpha);
- }
- }
- }
- // Draw back button
- Texture2D backTexture = isBackButtonPressed ? buttonPressedTexture : buttonRegularTexture;
- spriteBatch.Draw(backTexture, backButtonBounds, Color.Red * TransitionAlpha);
- string backText = "X";
- Vector2 backTextSize = ScreenManager.Font.MeasureString(backText);
- Vector2 backTextPos = new Vector2(
- backButtonBounds.X + (backButtonBounds.Width - backTextSize.X) / 2,
- backButtonBounds.Y + (backButtonBounds.Height - backTextSize.Y) / 2);
- spriteBatch.DrawString(ScreenManager.Font, backText, backTextPos, Color.White * TransitionAlpha);
- // Draw page navigation buttons
- if (currentPage > 0)
- {
- Texture2D prevTexture = isPrevButtonPressed ? buttonPressedTexture : buttonRegularTexture;
- spriteBatch.Draw(prevTexture, prevButtonBounds, Color.White * TransitionAlpha);
- string prevText = Resources.Previous;
- Vector2 prevTextSize = ScreenManager.RegularFont.MeasureString(prevText);
- Vector2 prevTextPos = new Vector2(
- prevButtonBounds.X + (prevButtonBounds.Width - prevTextSize.X) / 2,
- prevButtonBounds.Y + (prevButtonBounds.Height - prevTextSize.Y) / 2);
- spriteBatch.DrawString(ScreenManager.RegularFont, prevText, prevTextPos, Color.Black * TransitionAlpha);
- }
- if (currentPage < TotalPages - 1)
- {
- Texture2D nextTexture = isNextButtonPressed ? buttonPressedTexture : buttonRegularTexture;
- spriteBatch.Draw(nextTexture, nextButtonBounds, Color.White * TransitionAlpha);
- string nextText = Resources.Next;
- Vector2 nextTextSize = ScreenManager.RegularFont.MeasureString(nextText);
- Vector2 nextTextPos = new Vector2(
- nextButtonBounds.X + (nextButtonBounds.Width - nextTextSize.X) / 2,
- nextButtonBounds.Y + (nextButtonBounds.Height - nextTextSize.Y) / 2);
- spriteBatch.DrawString(ScreenManager.RegularFont, nextText, nextTextPos, Color.Black * TransitionAlpha);
- }
- // Draw page indicator
- string pageText = string.Format(Resources.PageIndicator, currentPage + 1, TotalPages);
- Vector2 pageTextSize = ScreenManager.RegularFont.MeasureString(pageText);
- Vector2 pageTextPos = new Vector2(
- safeArea.Center.X - pageTextSize.X / 2,
- safeArea.Bottom - 55);
- spriteBatch.DrawString(ScreenManager.RegularFont, pageText, pageTextPos, Color.White * TransitionAlpha);
- spriteBatch.End();
- base.Draw(gameTime);
- }
- }
- enum SettingType
- {
- Header,
- Counter,
- Slider,
- Cycle,
- Checkbox
- }
- class SettingItem
- {
- public SettingType Type { get; set; }
- public string Label { get; set; }
- public Func<string> GetValue { get; set; }
- public Action OnClick { get; set; }
- public Action OnIncrease { get; set; }
- public Action OnDecrease { get; set; }
- public Rectangle Bounds { get; set; }
- }
- }
|