Skip to content

Commit

Permalink
#108 Now for all InputField extension methods there are also the same…
Browse files Browse the repository at this point in the history
… ones for the TMP_InputField
  • Loading branch information
cs-util committed Nov 16, 2023
1 parent 69e7177 commit 9e9d901
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TMPro;
using UnityEngine;

namespace com.csutil {
Expand Down Expand Up @@ -43,8 +44,24 @@ public static T Get<T>(this Dictionary<string, Link> self, string id) {
public static T Get<T>(this Link self) {
if (typeof(T) == typeof(GameObject)) { return (T)(object)self.gameObject; }
var comp = self.GetComponentV2<T>();
if (comp == null) { CheckTmpAlternativePossible<T>(self); }
return comp == null ? (T)(object)null : comp;
}

/// <summary> This method checks if the UI already switched to using TMP while the code still uses the
/// old UI components and throws in improved exception instead of just returning null </summary>
private static void CheckTmpAlternativePossible<T>(Link self) {
if (typeof(T) == typeof(UnityEngine.UI.Text)) {
if (self.HasComponent<TMP_Text>(out var tmpText)) {
throw Log.e("Found TMP_Text instead of UnityEngine.UI.Text for " + self.id, tmpText);
}
} else if (typeof(T) == typeof(UnityEngine.UI.InputField)) {
if (self.HasComponent<TMP_InputField>(out var tmpInputField)) {
throw Log.e("Found TMP_InputField instead of UnityEngine.UI.InputField for " + self.id, tmpInputField);
}
}
}

}

}
Original file line number Diff line number Diff line change
@@ -1,21 +1,40 @@
using System;
using com.csutil.model.immutable;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace com.csutil {

public static class UiExtensionsForReduxSubState {

public static void SubscribeToStateChanges<T, S>(this TMP_Text self, SubState<T, S> subState, Func<S, string> getSubState) {
SubscribeToStateChanges(self, subState, getSubState, newText => self.text = newText);
}

[Obsolete("Use TMP_Text instead of Text")]
public static void SubscribeToStateChanges<T, S>(this Text self, SubState<T, S> subState, Func<S, string> getSubState) {
SubscribeToStateChanges(self, subState, getSubState, newText => self.text = newText);
}

public static void SetSubState<T,S>(this InputField self, SubState<T, S> subState, Func<S, string> getSubState, Action<string> onValueChanged) {
public static void SetSubState<T, S>(this TMP_InputField self, SubState<T, S> subState, Func<S, string> getSubState, Action<string> onValueChanged) {
if (self.IsNullOrDestroyed()) { throw new ArgumentNullException("self(InputField) must not be null!"); }
self.SubscribeToStateChanges(subState, getSubState);
self.AddOnValueChangedActionThrottled(onValueChanged);
}

[Obsolete("Use TMP_InputField instead of InputField")]
public static void SetSubState<T, S>(this InputField self, SubState<T, S> subState, Func<S, string> getSubState, Action<string> onValueChanged) {
if (self.IsNullOrDestroyed()) { throw new ArgumentNullException("self(InputField) must not be null!"); }
self.SubscribeToStateChanges(subState, getSubState);
self.AddOnValueChangedActionThrottled(onValueChanged);
}

public static void SubscribeToStateChanges<T, S>(this TMP_InputField self, SubState<T, S> subState, Func<S, string> getSubState) {
SubscribeToStateChanges(self, subState, getSubState, newText => self.text = newText);
}

[Obsolete("Use TMP_InputField instead of InputField")]
public static void SubscribeToStateChanges<T, S>(this InputField self, SubState<T, S> subState, Func<S, string> getSubState) {
SubscribeToStateChanges(self, subState, getSubState, newText => self.text = newText);
}
Expand All @@ -29,6 +48,9 @@ public static void SubscribeToStateChanges<T, S>(this Slider self, SubState<T, S
}

private static void SubscribeToStateChanges<T, S, Sub>(UnityEngine.Object ui, SubState<T, S> sub, Func<S, Sub> getSubState, Action<Sub> updateUi) {
if (ui.IsNullOrDestroyed()) {
throw new ArgumentNullException("The Unity UI object must not be null!");
}
var subSub = sub.GetSubStateForUnity(ui, getSubState);
subSub.onStateChanged += () => { updateUi(subSub.GetState()); };
}
Expand All @@ -47,6 +69,9 @@ public static SubState<T, Sub> GetSubStateForUnity<T, Sub>(this IDataStore<T> st
}

public static SubState<T, SubSub> GetSubStateForUnity<T, Sub, SubSub>(this SubState<T, Sub> parentSubState, UnityEngine.Object context, Func<Sub, SubSub> getSubState, bool eventsAlwaysInMainThread = true) {
if (context.IsNullOrDestroyed()) {
throw new ArgumentNullException("The Unity context object must not be null!");
}
var subState = parentSubState.GetSubState(getSubState);
var ownListenerInParent = parentSubState.AddStateChangeListener(getSubState, newSubState => {
if (eventsAlwaysInMainThread) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
using System;
using com.csutil.ui;
using TMPro;
using UnityEngine.Events;
using UnityEngine.UI;

namespace com.csutil {

public static class UiInputFieldExtensions {

public static UnityAction<string> SetOnValueChangedActionThrottled(this TMP_InputField self, Action<string> onValueChanged, double delayInMs = 500) {
if (self.onValueChanged != null && self.onValueChanged.GetPersistentEventCount() > 0) {
Log.w("Overriding old onValueChanged listener for input field " + self, self.gameObject);
}
self.onValueChanged = new TMP_InputField.OnChangeEvent(); // clear previous onValueChanged listeners
return AddOnValueChangedActionThrottled(self, onValueChanged, delayInMs);
}

[Obsolete("Use TMP_InputField instead of InputField")]
public static UnityAction<string> SetOnValueChangedActionThrottled(this InputField self, Action<string> onValueChanged, double delayInMs = 500) {
if (self.onValueChanged != null && self.onValueChanged.GetPersistentEventCount() > 0) {
Log.w("Overriding old onValueChanged listener for input field " + self, self.gameObject);
Expand All @@ -14,6 +25,16 @@ public static UnityAction<string> SetOnValueChangedActionThrottled(this InputFie
return AddOnValueChangedActionThrottled(self, onValueChanged, delayInMs);
}

public static UnityAction<string> AddOnValueChangedActionThrottled(this TMP_InputField self, Action<string> onValueChanged, double delayInMs = 500) {
EventHandler<string> action = (_, newText) => { onValueChanged(newText); };
var throttledAction = action.AsThrottledDebounce(delayInMs, skipFirstEvent: true);
return self.AddOnValueChangedAction((newText) => {
throttledAction(self, newText);
return true;
});
}

[Obsolete("Use TMP_InputField instead of InputField")]
public static UnityAction<string> AddOnValueChangedActionThrottled(this InputField self, Action<string> onValueChanged, double delayInMs = 500) {
EventHandler<string> action = (_, newText) => { onValueChanged(newText); };
var throttledAction = action.AsThrottledDebounce(delayInMs, skipFirstEvent: true);
Expand All @@ -23,18 +44,39 @@ public static UnityAction<string> AddOnValueChangedActionThrottled(this InputFie
});
}

public static void SelectV2(this TMP_InputField self) {
self.Select();
self.ActivateInputField();
}

/// <summary> Sets focus on the input field </summary>
[Obsolete("Use TMP_InputField instead of InputField")]
public static void SelectV2(this InputField self) {
self.Select();
self.ActivateInputField();
}

public static void SetTextLocalizedWithNotify(this TMP_InputField self, string text) {
self.SelectV2(); // Without this the change listeners are not triggered
self.textLocalized(text);
}

/// <summary> Sets the input text localized which will notify all UI listeners </summary>
[Obsolete("Use TMP_InputField instead of InputField")]
public static void SetTextLocalizedWithNotify(this InputField self, string text) {
self.SelectV2(); // Without this the change listeners are not triggered
self.textLocalized(text);
}

public static UnityAction<string> SetOnValueChangedAction(this TMP_InputField self, Func<string, bool> onValueChanged) {
if (self.onValueChanged != null && self.onValueChanged.GetPersistentEventCount() > 0) {
Log.w("Overriding old onValueChanged listener for input field " + self, self.gameObject);
}
self.onValueChanged = new TMP_InputField.OnChangeEvent(); // clear previous onValueChanged listeners
return AddOnValueChangedAction(self, onValueChanged);
}

[Obsolete("Use TMP_InputField instead of InputField")]
public static UnityAction<string> SetOnValueChangedAction(this InputField self, Func<string, bool> onValueChanged) {
if (self.onValueChanged != null && self.onValueChanged.GetPersistentEventCount() > 0) {
Log.w("Overriding old onValueChanged listener for input field " + self, self.gameObject);
Expand All @@ -43,6 +85,30 @@ public static UnityAction<string> SetOnValueChangedAction(this InputField self,
return AddOnValueChangedAction(self, onValueChanged);
}

public static UnityAction<string> AddOnValueChangedAction(this TMP_InputField self, Func<string, bool> onValueChanged, bool skipChangesByLogic = true) {
if (self.IsNullOrDestroyed()) {
throw new ArgumentNullException("self (InputField)");
}
if (onValueChanged != null) {
var oldText = self.text;
UnityAction<string> newListener = (newText) => {
if (newText == oldText) { return; }
// Ignore event event if it was triggered through code, only fire for actual user input:
if (skipChangesByLogic && !self.ChangeWasTriggeredByUserThroughEventSystem()) { return; }
if (!onValueChanged(newText)) {
self.text = oldText;
} else {
oldText = newText;
EventBus.instance.Publish(EventConsts.catUi + UiEvents.INPUTFIELD_CHANGED, self, newText);
}
};
self.onValueChanged.AddListener(newListener);
return newListener;
}
return null;
}

[Obsolete("Use TMP_InputField instead of InputField")]
public static UnityAction<string> AddOnValueChangedAction(this InputField self, Func<string, bool> onValueChanged, bool skipChangesByLogic = true) {
if (self.IsNullOrDestroyed()) {
throw new ArgumentNullException("self (InputField)");
Expand All @@ -67,4 +133,5 @@ public static UnityAction<string> AddOnValueChangedAction(this InputField self,
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,36 @@
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
using TMPro;
using UnityEngine.UI;

namespace com.csutil {

public static class LocalizationExtensions {

public static void textLocalized(this TMP_InputField self, string key, params object[] args) {
I18n i18n = I18n.instance(self);
if (i18n == null) { i18n = SetupDefaultI18nInstance(self).Result; }
var localizedText = i18n.Get(key, args);
if (localizedText != self.text) { self.text = localizedText; }
}

[Obsolete("Use TMP_InputField instead of InputField")]
public static void textLocalized(this InputField self, string key, params object[] args) {
I18n i18n = I18n.instance(self);
if (i18n == null) { i18n = SetupDefaultI18nInstance(self).Result; }
var localizedText = i18n.Get(key, args);
if (localizedText != self.text) { self.text = localizedText; }
}

public static void textLocalized(this TMP_Text self, string key, params object[] args) {
I18n i18n = I18n.instance(self);
if (i18n == null) { i18n = SetupDefaultI18nInstance(self).Result; }
var localizedText = i18n.Get(key, args);
if (localizedText != self.text) { self.text = localizedText; }
}

[Obsolete("Use TMP_Text instead of Text")]
public static void textLocalized(this Text self, string key, params object[] args) {
I18n i18n = I18n.instance(self);
if (i18n == null) { i18n = SetupDefaultI18nInstance(self).Result; }
Expand Down

0 comments on commit 9e9d901

Please sign in to comment.