Skip to content

Commit

Permalink
add four choice popup menus
Browse files Browse the repository at this point in the history
  • Loading branch information
misternebula committed Sep 10, 2023
1 parent fe79d26 commit 271b195
Show file tree
Hide file tree
Showing 5 changed files with 457 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/OWML.Common/Interfaces/Menus/IOWMLFourChoicePopupMenu.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace OWML.Common
{
public interface IOWMLFourChoicePopupMenu
{
event PopupConfirmEvent OnPopupConfirm1;
event PopupConfirmEvent OnPopupConfirm2;
event PopupConfirmEvent OnPopupConfirm3;
event PopupValidateEvent OnPopupValidate;
event PopupCancelEvent OnPopupCancel;

void EnableMenu(bool value);
}
}
2 changes: 2 additions & 0 deletions src/OWML.Common/Interfaces/Menus/IPopupMenuManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public interface IPopupMenuManager

public IOWMLThreeChoicePopupMenu CreateThreeChoicePopup(string message, string confirm1Text, string confirm2Text, string cancelText);

public IOWMLFourChoicePopupMenu CreateFourChoicePopup(string message, string confirm1Text, string confirm2Text, string confirm3Text, string cancelText);

public IOWMLPopupInputMenu CreateInputFieldPopup(string message, string placeholderMessage, string confirmText, string cancelText);
}
}
376 changes: 376 additions & 0 deletions src/OWML.ModHelper.Menus/CustomInputs/OWMLFourChoicePopupMenu.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,376 @@
using System;
using OWML.Common;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityEngine;

namespace OWML.ModHelper.Menus.CustomInputs
{
public class OWMLFourChoicePopupMenu : Menu, IOWMLFourChoicePopupMenu
{
public Text _labelText;
public SubmitAction _cancelAction;
public SubmitAction _ok1Action;
public SubmitAction _ok2Action;
public SubmitAction _ok3Action;
public ButtonWithHotkeyImageElement _cancelButton;
public ButtonWithHotkeyImageElement _confirmButton1;
public ButtonWithHotkeyImageElement _confirmButton2;
public ButtonWithHotkeyImageElement _confirmButton3;
public Canvas _rootCanvas;

protected Canvas _popupCanvas;
protected GameObject _blocker;
protected bool _closeMenuOnOk = true;
protected IInputCommands _ok1Command;
protected IInputCommands _ok2Command;
protected IInputCommands _ok3Command;
protected IInputCommands _cancelCommand;
protected bool _usingGamepad;

public event PopupConfirmEvent OnPopupConfirm1;
public event PopupConfirmEvent OnPopupConfirm2;
public event PopupConfirmEvent OnPopupConfirm3;
public event PopupValidateEvent OnPopupValidate;
public event PopupCancelEvent OnPopupCancel;

public override Selectable GetSelectOnActivate()
{
_usingGamepad = OWInput.UsingGamepad();
return _usingGamepad ? null : _selectOnActivate;
}

public virtual void SetUpPopup(
string message,
IInputCommands ok1Command,
IInputCommands ok2Command,
IInputCommands ok3Command,
IInputCommands cancelCommand,
ScreenPrompt ok1Prompt,
ScreenPrompt ok2Prompt,
ScreenPrompt ok3Prompt,
ScreenPrompt cancelPrompt,
bool closeMenuOnOk = true,
bool setCancelButtonActive = true)
{
_labelText.text = message;
SetUpPopupCommands(ok1Command, ok2Command, ok3Command, cancelCommand, ok1Prompt, ok2Prompt, ok3Prompt, cancelPrompt);
if (!(_cancelAction != null))
{
Debug.LogWarning("PopupMenu.SetUpPopup Cancel button not set!");
return;
}

_cancelAction.gameObject.SetActive(setCancelButtonActive);
if (setCancelButtonActive)
{
_selectOnActivate = _cancelAction.GetRequiredComponent<Selectable>();
return;
}

_selectOnActivate = _ok1Action.GetRequiredComponent<Selectable>();
}

public virtual void SetUpPopupCommands(
IInputCommands ok1Command,
IInputCommands ok2Command,
IInputCommands ok3Command,
IInputCommands cancelCommand,
ScreenPrompt ok1Prompt,
ScreenPrompt ok2Prompt,
ScreenPrompt ok3Prompt,
ScreenPrompt cancelPrompt)
{
_ok1Command = ok1Command;
_ok2Command = ok2Command;
_ok3Command = ok3Command;
_cancelCommand = cancelCommand;
_confirmButton1.SetPrompt(ok1Prompt, InputMode.Menu);
_confirmButton2.SetPrompt(ok2Prompt, InputMode.Menu);
_confirmButton3.SetPrompt(ok3Prompt, InputMode.Menu);
_cancelButton.SetPrompt(cancelPrompt, InputMode.Menu);
}

public virtual void ResetPopup()
{
_labelText.text = "";
_ok1Command = null;
_ok2Command = null;
_ok3Command = null;
_cancelCommand = null;
_cancelButton.SetPrompt(null, InputMode.Menu);
_confirmButton1.SetPrompt(null, InputMode.Menu);
_confirmButton2.SetPrompt(null, InputMode.Menu);
_confirmButton3.SetPrompt(null, InputMode.Menu);
_selectOnActivate = null;
}

public virtual void CloseMenuOnOk(bool value)
{
_closeMenuOnOk = value;
}

public virtual bool EventsHaveListeners()
{
return OnPopupCancel != null
|| OnPopupConfirm1 != null
|| OnPopupConfirm2 != null
|| OnPopupConfirm3 != null;
}

public override void InitializeMenu()
{
base.InitializeMenu();
if (_cancelAction != null)
{
_cancelAction.OnSubmitAction += InvokeCancel;
}

_ok1Action.OnSubmitAction += InvokeOk1;
_ok2Action.OnSubmitAction += InvokeOk2;
_ok3Action.OnSubmitAction += InvokeOk3;
_popupCanvas = gameObject.GetAddComponent<Canvas>();
_popupCanvas.overrideSorting = true;
_popupCanvas.sortingOrder = 30000;
gameObject.GetAddComponent<GraphicRaycaster>();
gameObject.GetAddComponent<CanvasGroup>();
}

protected virtual void Update()
{
if (_cancelCommand != null && OWInput.IsNewlyPressed(_cancelCommand, InputMode.All))
{
InvokeCancel();
return;
}

if (_ok1Command != null && OWInput.IsNewlyPressed(_ok1Command, InputMode.All))
{
InvokeOk1();
return;
}

if (_ok2Command != null && OWInput.IsNewlyPressed(_ok2Command, InputMode.All))
{
InvokeOk2();
return;
}

if (_ok3Command != null && OWInput.IsNewlyPressed(_ok3Command, InputMode.All))
{
InvokeOk3();
return;
}

if (_usingGamepad != OWInput.UsingGamepad())
{
_usingGamepad = OWInput.UsingGamepad();
if (_usingGamepad)
{
Locator.GetMenuInputModule().SelectOnNextUpdate(null);
return;
}

Locator.GetMenuInputModule().SelectOnNextUpdate(_selectOnActivate);
}
}

public override void EnableMenu(bool value)
{
if (value == _enabledMenu)
{
return;
}

_enabledMenu = value;
if (_enabledMenu && !_initialized)
{
InitializeMenu();
}

if (!_addToMenuStackManager)
{
if (_enabledMenu)
{
Activate();
if (_selectOnActivate != null)
{
var component = _selectOnActivate.GetComponent<SelectableAudioPlayer>();
if (component != null)
{
component.SilenceNextSelectEvent();
}

Locator.GetMenuInputModule().SelectOnNextUpdate(_selectOnActivate);
return;
}
}
else
{
Deactivate(false);
}

return;
}

if (_enabledMenu)
{
MenuStackManager.SharedInstance.Push(this, true);
return;
}

if (MenuStackManager.SharedInstance.Peek() == this)
{
MenuStackManager.SharedInstance.Pop(false);
return;
}

Debug.LogError("Cannot disable Menu unless it is on the top the MenuLayerManager stack. Current menu on top: " + MenuStackManager.SharedInstance.Peek().name);
}

public override void Activate()
{
base.Activate();
if (_rootCanvas != null)
{
_blocker = CreateBlocker(_rootCanvas);
}
}

public override void Deactivate(bool keepPreviousMenuVisible = false)
{
if (_rootCanvas != null)
{
DestroyBlocker(_blocker);
}

var component = _cancelAction.GetComponent<UIStyleApplier>();
if (component != null)
{
component.ChangeState(UIElementState.NORMAL, true);
}

component = _ok1Action.GetComponent<UIStyleApplier>();
if (component != null)
{
component.ChangeState(UIElementState.NORMAL, true);
}

component = _ok2Action.GetComponent<UIStyleApplier>();
if (component != null)
{
component.ChangeState(UIElementState.NORMAL, true);
}

component = _ok3Action.GetComponent<UIStyleApplier>();
if (component != null)
{
component.ChangeState(UIElementState.NORMAL, true);
}

base.Deactivate(keepPreviousMenuVisible);
}

public override void OnCancelEvent(GameObject selectedObj, BaseEventData eventData)
{
base.OnCancelEvent(selectedObj, eventData);
OnPopupCancel?.Invoke();
}

protected virtual void InvokeCancel()
{
EnableMenu(false);
OnPopupCancel?.Invoke();
}

protected virtual bool Validate()
{
var flag = true;
if (OnPopupValidate != null)
{
var invocationList = OnPopupValidate.GetInvocationList();
for (var i = 0; i < invocationList.Length; i++)
{
var flag2 = (bool)invocationList[i].DynamicInvoke(Array.Empty<object>());
flag = flag && flag2;
}
}

return flag;
}

protected virtual void InvokeOk1()
{
if (!Validate())
{
return;
}

if (_closeMenuOnOk)
{
EnableMenu(false);
}

OnPopupConfirm1?.Invoke();
}

protected virtual void InvokeOk2()
{
if (!Validate())
{
return;
}

if (_closeMenuOnOk)
{
EnableMenu(false);
}

OnPopupConfirm2?.Invoke();
}

protected virtual void InvokeOk3()
{
if (!Validate())
{
return;
}

if (_closeMenuOnOk)
{
EnableMenu(false);
}

OnPopupConfirm3?.Invoke();
}

protected virtual GameObject CreateBlocker(Canvas rootCanvas)
{
var gameObject = new GameObject("Blocker");
var rectTransform = gameObject.AddComponent<RectTransform>();
rectTransform.SetParent(rootCanvas.transform, false);
rectTransform.anchorMin = Vector3.zero;
rectTransform.anchorMax = Vector3.one;
rectTransform.sizeDelta = Vector2.zero;
var canvas = gameObject.AddComponent<Canvas>();
canvas.overrideSorting = true;
canvas.sortingLayerID = _popupCanvas.sortingLayerID;
canvas.sortingOrder = _popupCanvas.sortingOrder - 1;
gameObject.AddComponent<GraphicRaycaster>();
var image = gameObject.AddComponent<Image>();
if (Locator.GetUIStyleManager() != null)
{
image.color = Locator.GetUIStyleManager().GetPopupBlockerColor();
return gameObject;
}

image.color = Color.clear;
return gameObject;
}

protected virtual void DestroyBlocker(GameObject blocker)
{
Destroy(blocker);
}
}
}
Loading

0 comments on commit 271b195

Please sign in to comment.