Skip to content

Commit

Permalink
Add Button and Screen
Browse files Browse the repository at this point in the history
  • Loading branch information
neilsarkar committed Jul 26, 2020
1 parent 061df16 commit 061ee97
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 15 deletions.
32 changes: 32 additions & 0 deletions Runtime/Navigation/Button.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using UnityEngine;
using UnityEngine.EventSystems;

namespace VioletUI{
[ExecuteAlways]
public class Button : UnityEngine.UI.Button {
public ScreenId visitScreen;

public override void OnSubmit(BaseEventData eventData) {
base.OnSubmit(eventData);
Submit();
}

public override void OnPointerClick(PointerEventData eventData) {
base.OnPointerClick(eventData);
Submit();
}

Navigator navigator;
protected override void Awake() {
base.Awake();
navigator = gameObject.GetComponentInParent<Navigator>();
}

protected virtual void Submit() {
Violet.Log($"Button {name} clicked");
if (visitScreen != ScreenId.None) {
navigator.Visit(visitScreen);
}
}
}
}
11 changes: 11 additions & 0 deletions Runtime/Navigation/Button.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 13 additions & 8 deletions Runtime/Navigation/Navigator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class Navigator : TidyBehaviour {
[NonSerialized] CancellationTokenSource canceler = null;
#endregion

void Awake() {
void Start() {
if (!Application.isPlaying) { return; }
LoadScreens();
VisitFirstScreen();
Expand All @@ -54,10 +54,15 @@ void LoadScreens() {

ScreenId screenId = ScreenId.None;
foreach (Screen screen in GetComponentsInChildren<Screen>(true)) {
var isValid = Enum.TryParse(screen.name, out screenId);
var isValid = Enum.TryParse(ScreenIdGenerator.Sanitize(screen.name), out screenId);
if (!isValid) {
#if UNITY_EDITOR
Violet.LogWarning($"Couldn't find {screen.name}, regenerating. Try pressing play again. ScreenId contains {string.Join(", ", Enum.GetNames(typeof(ScreenId)))}");
RegenerateEnums();
throw new VioletException($"{screen.name} does not have a valid ScreenId.");
EditorApplication.ExitPlaymode();
#else
throw new VioletException($"{screen.name} does not have a valid ScreenId. ScreenId contains {string.Join(", ", Enum.GetNames(typeof(ScreenId)))}"");
#endif
}

if (hasCamera) {
Expand Down Expand Up @@ -138,9 +143,10 @@ public void CloseModal() {
// Sigh.
// https://forum.unity.com/threads/ability-to-add-enum-argument-to-button-functions.270817/
/// <summary>
/// Visit by string is for use in UnityEvents only. In code, please use Visit by enum
/// Visit by string is for use in UnityEvents, since the editor doesn't show functions with enum arguments
/// </summary>
/// <param name="screenIdString"></param>
[Obsolete("This is for us in UnityEvents only since they can't accept an enum. Use `Visit(ScreenId screenId)` instead")]
public void Visit(string screenIdString) {
ScreenId screenId;
var isValid = Enum.TryParse<ScreenId>(screenIdString.Replace(" ", ""), out screenId);
Expand All @@ -166,7 +172,7 @@ protected virtual void VisitFirstScreen() {

ScreenId ScreenToScreenId(Screen screen) {
ScreenId ret;
var slug = screen.name.Replace(" ", "");
var slug = ScreenIdGenerator.Sanitize(screen.name);
var ok = Enum.TryParse<ScreenId>(slug, out ret);

if (!ok) {
Expand All @@ -180,11 +186,12 @@ ScreenId ScreenToScreenId(Screen screen) {
[SerializeField, HideInInspector] ScreenId originalHomeScreen;

public void Edit(Screen screen) {
originalHomeScreen = homeScreen;
try {
homeScreen = ScreenToScreenId(screen);
} catch (VioletEnumException) {
ScreenIdGenerator.Generate(screen);
Violet.LogWarning($"Couldn't find {screen.name} in the ScreenId enum. This should be fixed if you hit edit again. If not, please report a bug.");
ScreenIdGenerator.Generate(screen);
return;
}

Expand All @@ -194,8 +201,6 @@ public void Edit(Screen screen) {

screen.gameObject.SetActive(true);
EditingScreen = screen;
originalHomeScreen = homeScreen;

}

public void FinishEditing(Screen screen = null) {
Expand Down
85 changes: 80 additions & 5 deletions Runtime/Navigation/Screen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
using System.Threading.Tasks;
using System.Threading;
using UniRx.Async;
using Sirenix.OdinInspector;
using System.Collections.Generic;
using UnityEngine.Events;
#if UNITY_EDITOR
using UnityEditor.Animations;
using UnityEngine.SceneManagement;
using UnityEditor.SceneManagement;
using UnityEditor;
Expand All @@ -13,27 +17,98 @@ namespace VioletUI {
[ExecuteAlways]
public class Screen : TidyBehaviour {

internal async UniTask<bool> Show(CancellationToken token) {
[Title("Show/Hide")]

[ValueDropdown("TriggerNames")] public string ShowAnimation;
[ValueDropdown("TriggerNames")] public string HideAnimation;
public UnityEvent OnShow;
public UnityEvent OnHide;

Animator animator;

void OnEnable() {
animator = gameObject.GetComponent<Animator>();
}

internal async UniTask<bool> Show(CancellationToken token = default, string triggerOverride = null) {
gameObject.SetActive(true);
await UniTask.DelayFrame(1);

// if (HasGate && Release.Flags[gate]) {
// OnGatedShow?.Invoke();
// } else {
// OnShow?.Invoke();
// }

var triggerName = triggerOverride == null ? ShowAnimation : triggerOverride;

try {
await Animate(triggerName, token);
} catch (OperationCanceledException) {
return false;
}

return true;
}

internal async UniTask<bool> Hide(CancellationToken token) {
internal async UniTask<bool> Hide(CancellationToken token = default, string triggerOverride = null) {
// uiEvents.lastSelected = EventSystem.current?.currentSelectedGameObject;
var triggerName = triggerOverride == null ? HideAnimation : triggerOverride;

bool ok = true;
try {
await Animate(triggerName, token);
} catch (OperationCanceledException) {
ok = false;
}
// if (HasGate && Release.Flags[gate]) {
// OnGatedHide?.Invoke();
// } else {
// OnHide?.Invoke();
// }
gameObject.SetActive(false);
await UniTask.DelayFrame(1);

return ok;
}

async UniTask<bool> Animate(string trigger, CancellationToken token = default) {
if (animator == null || trigger == null || trigger == string.Empty || trigger == "None" || trigger == "Null") { return true; }
if (!Application.isPlaying) { return true; }

animator.SetTrigger(trigger);
var state = animator.GetCurrentAnimatorStateInfo(0);
await UniTask.Delay((int)(state.length * 1000), false, PlayerLoopTiming.Update, token);
return true;
}

#if UNITY_EDITOR
List<string> TriggerNames() {
var animator = GetComponent<Animator>();
if (animator == null) { return new List<string>() { "(add animator component)" }; }

var animatorController = animator.runtimeAnimatorController as AnimatorController;
if (animatorController.parameters.Length == 0) { return new List<string>() { "(add triggers to animator)" }; }

var names = new List<string>() { "None" };
foreach (var trigger in animatorController.parameters) {
if (trigger.type != AnimatorControllerParameterType.Trigger) { continue; }
names.Add(trigger.name);
}

return names;
}

public void Update() {
EditorSceneManager.sceneSaved -= EditorSceneManager_sceneSaved;
EditorSceneManager.sceneSaved += EditorSceneManager_sceneSaved;
}

void EditorSceneManager_sceneSaved(Scene scene) {
Violet.Log($"Scene saved, will update the {name} fabio");
try {
Violet.Log($"Scene saved, will update the {name} fabio");
} catch(MissingReferenceException) {}
}
#else
List<string> TriggerNames() { return null; }
#endif

}
Expand Down
4 changes: 2 additions & 2 deletions Runtime/Navigation/ScreenIdGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ static List<string> Filter(List<string> screens) {
var ret = new List<string>();
foreach (var screen in screens.Distinct()) {
if (screen == null) { continue; }
var name = sanitize(screen);
var name = Sanitize(screen);
if (Enum.TryParse<ScreenId>(name, out _)) { continue; }
Violet.Log($"Adding new screen to enum - {name}");
ret.Add(name);
Expand Down Expand Up @@ -69,7 +69,7 @@ static void AddScreens(List<string> screens) {
AssetDatabase.Refresh();
}

static string sanitize(string s) {
public static string Sanitize(string s) {
return s.Replace(" ", "");
}

Expand Down

0 comments on commit 061ee97

Please sign in to comment.