diff --git a/CHANGELOG.md b/CHANGELOG.md
index da291f6..ccb035b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [0.2.0] - 2020-07-25
+
+### Added
+- Navigator
+- Screen
+
+## [0.1.42] - 2020-07-21
+
+### Added
+- ChildView
+- StateMonobehaviour
+
## [0.1.0] - 2020-07-19
### Added
diff --git a/Editor/ScreenEditor.cs b/Editor/ScreenEditor.cs
index f173432..d0d323b 100644
--- a/Editor/ScreenEditor.cs
+++ b/Editor/ScreenEditor.cs
@@ -15,15 +15,10 @@ public static class ScreenEditor {
private static GUIStyle singleStyle, leftStyle, rightStyle;
static Navigator navigator;
- static Color violet = new Color(0.898f, 0.745f, 0.935f);
- static Color saturatedViolet;
static ScreenEditor() {
EditorApplication.hierarchyWindowItemOnGUI -= DrawHierarchyItem;
EditorApplication.hierarchyWindowItemOnGUI += DrawHierarchyItem;
- float h,s,v;
- Color.RGBToHSV(violet, out h, out s, out v);
- saturatedViolet = Color.HSVToRGB(h, 1f, 1f);
}
static void DrawHierarchyItem(int instanceID, Rect rect) {
@@ -86,7 +81,7 @@ static bool Button(Rect rect, string label, bool isActive = false) {
// set color to violet if active
var originalColor = GUI.color;
- GUI.color = isActive ? violet : originalColor;
+ GUI.color = isActive ? Violet.Hue : originalColor;
var response = GUI.Button(rect, new GUIContent(label), style);
GUI.color = originalColor;
diff --git a/Runtime/Exceptions.cs b/Runtime/Exceptions.cs
index 8d112c3..5f5f38f 100644
--- a/Runtime/Exceptions.cs
+++ b/Runtime/Exceptions.cs
@@ -7,7 +7,8 @@ public Bail(string message) : base(message) { }
}
public class VioletException : Exception {
- public VioletException(string message) : base(message) { }
+ public VioletException(string message) :
+ base($"{Violet.Color("VioletUI")} | {message}") { }
}
public class VioletEnumException : VioletException {
diff --git a/Runtime/Navigation/Navigator.cs b/Runtime/Navigation/Navigator.cs
index 1787896..e079dda 100644
--- a/Runtime/Navigation/Navigator.cs
+++ b/Runtime/Navigation/Navigator.cs
@@ -11,9 +11,9 @@
namespace VioletUI {
///
- /// Screens maintains a map of enum to menu screens.
+ /// Navigator maintains a map of enum to menu screens.
///
- /// It is primarily used to navigate between screens, and also exposes the and lifecycle events.
+ /// It is used to navigate between screens and exposes , , , and .
///
[ExecuteAlways]
public class Navigator : TidyBehaviour {
@@ -46,15 +46,14 @@ void Awake() {
VisitFirstScreen();
}
void LoadScreens() {
- if (transform.childCount == 0) {
- throw new Exception($"Tried to create a NavigationController with no children - try adding some NavigationScreens to {gameObject.name}");
- }
+ if (transform.childCount == 0) { return; }
ScreenId screenId = ScreenId.None;
foreach (Screen screen in GetComponentsInChildren(true)) {
var isValid = Enum.TryParse(screen.name, out screenId);
if (!isValid) {
- throw new VioletException($"{screen.name} does not have a valid ScreenId. Make sure this screen is added to MenuBuilder.");
+ RegenerateEnums();
+ throw new VioletException($"{screen.name} does not have a valid ScreenId.");
}
if (hasCamera) {
@@ -82,7 +81,7 @@ void LoadScreens() {
///
public async void Visit(ScreenId screenId) {
if (!screens.ContainsKey(screenId)) {
- throw new Exception($"Tried to visit {screenId} but it doesn't exist in the current scene. You'll want to add the {screenId} prefab to this scene or to the MenuBuilder prefab. Or change the Home Screen to the screen you want.");
+ throw new VioletException($"Tried to visit {screenId} but it doesn't exist in the current scene. You'll want to add the {screenId} prefab to this scene or to the MenuBuilder prefab. Or change the Home Screen to the screen you want.");
}
// if we're currently in a transition, cancel the transition and run OnHide/OnShow immediately
@@ -142,7 +141,7 @@ public void Visit(string screenIdString) {
ScreenId screenId;
var isValid = Enum.TryParse(screenIdString.Replace(" ", ""), out screenId);
if (!isValid) {
- throw new Exception($"Couldn't find a screen with the id {screenIdString.Replace(" ", "")}. Please check the spelling.");
+ throw new VioletException($"Couldn't find a screen with the id {screenIdString.Replace(" ", "")}. Please check the spelling.");
}
Visit(screenId);
}
@@ -151,7 +150,7 @@ public void ShowModal (string screenIdString) {
ScreenId screenId;
var isValid = Enum.TryParse(screenIdString.Replace(" ", ""), out screenId);
if (!isValid) {
- throw new Exception($"Couldn't find a screen with the id {screenIdString.Replace(" ", "")}. Please check the spelling.");
+ throw new VioletException($"Couldn't find a screen with the id {screenIdString.Replace(" ", "")}. Please check the spelling.");
}
ShowModal(screenId);
@@ -181,7 +180,7 @@ public void Edit(Screen screen) {
homeScreen = ScreenToScreenId(screen);
} catch (VioletEnumException) {
ScreenIdGenerator.Generate(screen);
- Debug.LogWarning($"VioletUI - Couldn't find {screen.name} in the ScreenId enum. This should be fixed if you try your action again. If not, please report a bug.");
+ 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.");
return;
}
diff --git a/Runtime/Navigation/ScreenId.cs b/Runtime/Navigation/ScreenId.cs
index eed3b1c..77ecd3f 100644
--- a/Runtime/Navigation/ScreenId.cs
+++ b/Runtime/Navigation/ScreenId.cs
@@ -1,6 +1,6 @@
//Names are automatically added through ScreenIdGenerator.cs, deletions are done manually :)
namespace VioletUI {
public enum ScreenId {
- None = 0
+ None = 0,
}
}
diff --git a/Runtime/Navigation/ScreenIdGenerator.cs b/Runtime/Navigation/ScreenIdGenerator.cs
index 4fb550e..ef75869 100644
--- a/Runtime/Navigation/ScreenIdGenerator.cs
+++ b/Runtime/Navigation/ScreenIdGenerator.cs
@@ -2,8 +2,10 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Reflection;
using System.Text;
using UnityEditor;
+using UnityEditor.Compilation;
using UnityEngine;
namespace VioletUI {
@@ -30,10 +32,11 @@ public static void Generate(List screens) {
static List Filter(List screens) {
var ret = new List();
- foreach (var screen in screens) {
+ foreach (var screen in screens.Distinct()) {
if (screen == null) { continue; }
var name = sanitize(screen);
- if (Enum.TryParse(screen, out _)) { continue; }
+ if (Enum.TryParse(name, out _)) { continue; }
+ Violet.Log($"Adding new screen to enum - {name}");
ret.Add(name);
}
return ret;
@@ -60,13 +63,31 @@ static void AddScreens(List screens) {
}
sb.AppendLine("\t}");
sb.AppendLine("}");
- string path = Path.GetFullPath("Packages/violetui/Runtime/Navigation/ScreenId.cs");
+ string path = $"{packagePath()}/Runtime/Navigation/ScreenId.cs";
File.WriteAllText(path, sb.ToString());
+ Violet.Log("Regenerating the ScreenId enum, this may take a second to recompile.");
AssetDatabase.Refresh();
}
static string sanitize(string s) {
return s.Replace(" ", "");
}
+
+ static string scriptPath() {
+ return null;
+ }
+ static string packagePath() {
+ foreach (var path in packagePaths) {
+ var paths = Directory.GetDirectories(path, "*violetui*", SearchOption.TopDirectoryOnly);
+ if (paths.Length > 0) { return paths[0];}
+ }
+ throw new VioletException("Can't find violetui in Library/PackageCache or Packages. Please report a bug.");
+ }
+ static string[] packagePaths = new string[] {
+ Path.GetFullPath("Library/PackageCache"),
+ Path.GetFullPath("Packages")
+ };
}
}
+
+
diff --git a/Runtime/StateMonoBehaviour.cs b/Runtime/StateMonoBehaviour.cs
index 2bc8962..04e3cc1 100644
--- a/Runtime/StateMonoBehaviour.cs
+++ b/Runtime/StateMonoBehaviour.cs
@@ -10,8 +10,8 @@
namespace VioletUI {
[ExecuteAlways]
- public abstract class StateMonoBehaviour : TidyBehaviour where TState : class, IState {
- public static StateMonoBehaviour Singleton;
+ public abstract class StateMonobehaviour : TidyBehaviour where TState : class, IState {
+ public static StateMonobehaviour Singleton;
public TState State;
[NonSerialized, HideInInspector] public TState LastState;
@@ -30,16 +30,19 @@ public Dispatcher Dispatcher {
public class View : View {
protected override TState State => Singleton?.State;
protected override TState LastState => Singleton?.LastState;
+ protected override Dispatcher Dispatcher => Dispatcher;
}
public abstract class RepeatView : RepeatView {
protected override TState State => Singleton?.State;
protected override TState LastState => Singleton?.LastState;
+ protected override Dispatcher Dispatcher => Dispatcher;
}
public abstract class ChildView : ChildView {
protected override TState State => Singleton?.State;
protected override TState LastState => Singleton?.LastState;
+ protected override Dispatcher Dispatcher => Dispatcher;
}
void Awake() {
diff --git a/Runtime/Views/View.cs b/Runtime/Views/View.cs
index 44fa932..4bb0f15 100644
--- a/Runtime/Views/View.cs
+++ b/Runtime/Views/View.cs
@@ -6,6 +6,10 @@
namespace VioletUI {
[ExecuteAlways]
public abstract class View : TidyBehaviour where TState : class, IState {
+ ///
+ /// A view requires a reference to State and LastState.
+ ///
+ ///
protected abstract TState State { get; }
protected abstract TState LastState { get; }
@@ -18,7 +22,7 @@ protected virtual void OnShow() { }
///
protected virtual void OnHide() { }
///
- /// ShouldRender is used to short circuit expensive render calls by focusing on parts of the state you care about.
+ /// IsDirty is used to short circuit expensive render calls by focusing on parts of the state you care about.
///
/// return `false` to avoid rendering
///
@@ -32,13 +36,21 @@ protected virtual void OnHide() { }
///
protected virtual void Render(TState state) { }
- Dispatcher m_dispatcher;
- protected Dispatcher dispatcher {
+ ///
+ /// dispatcher allows you to send Actions that
+ ///
+ protected virtual Dispatcher Dispatcher {
get {
- if (m_dispatcher == null) { m_dispatcher = new Dispatcher(State, LastState); }
- return m_dispatcher;
+ if (dispatcher == null) { dispatcher = new Dispatcher(State, LastState); }
+ return dispatcher;
}
}
+ Dispatcher dispatcher;
+
+ // convenience methods for logging in views
+ protected void Log(string s) { Violet.Log(s); }
+ protected void LogWarning(string s) { Violet.LogWarning(s); }
+ protected void LogError(string s) { Violet.LogError(s); }
// Internal methods are so that callers don't have to remember to call base. at the beginning of their implementations
internal virtual void OnShowInternal() {}
@@ -96,20 +108,20 @@ void OnDisable() {
void Warn(string msg) {
#if VIOLETDEV
- UnityEngine.Debug.LogWarning(msg);
+ Violet.LogWarning(msg);
#endif
}
void Verbose(string msg) {
#if VIOLETDEV && VIOLET_VERBOSE
- UnityEngine.Debug.Log(msg);
+ Violet.Log(msg);
#endif
}
#if UNITY_EDITOR
public virtual void Update() {
if (Application.isPlaying) { return; }
- if (State == null) { Debug.LogWarning("State is null"); return; }
+ if (State == null) { Warn("State is null"); return; }
State.OnChange -= State_OnChange;
State.OnChange += State_OnChange;
}
diff --git a/Runtime/Violet.cs b/Runtime/Violet.cs
new file mode 100644
index 0000000..6d09063
--- /dev/null
+++ b/Runtime/Violet.cs
@@ -0,0 +1,36 @@
+using UnityEngine;
+
+///
+/// Static utility methods
+///
+public static class Violet {
+ public static void Log(string s) {
+ Debug.Log($"{Color("VioletUI")} | {s}");
+ }
+
+ public static void LogWarning(string s) {
+ Debug.LogWarning($"{Color("VioletUI")} | {s}");
+ }
+
+ public static void LogError(string s) {
+ Debug.LogError($"{Color("VioletUI")} | {s}");
+ }
+
+ // #ceb2da
+ // hsl(282, 35%, 78%)
+ public static Color Hue = new Color(0.898f, 0.745f, 0.935f);
+
+ // #b300ff
+ // rgb(179, 0, 255)
+ // hsl(282, 100%, 50%)
+ public static Color BrightHue = new Color(179/255, 0, 1);
+ ///
+ /// Wraps `s` in tags for printing to unity console
+ ///
+ ///
+ ///
+ public static string Color(string s, string hex = "b300ff") {
+ return $"{s}";
+ }
+
+}
\ No newline at end of file
diff --git a/Runtime/Violet.cs.meta b/Runtime/Violet.cs.meta
new file mode 100644
index 0000000..cca7456
--- /dev/null
+++ b/Runtime/Violet.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d99eca75c51084b3d9908a751ba74a14
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: