diff --git a/BestiaryUI.cs b/BestiaryUI.cs
index db22e47..974bcb3 100644
--- a/BestiaryUI.cs
+++ b/BestiaryUI.cs
@@ -213,6 +213,10 @@ private int CustomSort(UIElement x, UIElement y) {
return x.CompareTo(y);
}
+ ///
+ /// Validates the NPC-name filter against all loaded NPC names.
+ /// If no match is found, removes the last character and triggers a blink to indicate invalid input.
+ ///
private void ValidateNPCFilter()
{
if (npcNameFilter.currentString.Length > 0)
@@ -231,6 +235,7 @@ private void ValidateNPCFilter()
if (!found)
{
npcNameFilter.SetText(npcNameFilter.currentString.Substring(0, npcNameFilter.currentString.Length - 1));
+ npcNameFilter.TriggerInvalidBlink();
}
}
updateNeeded = true;
@@ -383,4 +388,4 @@ private void ItemChecklistNewLootOnlyFilter_SelectedChanged(object sender, Event
updateNeeded = true;
}
}
-}
\ No newline at end of file
+}
diff --git a/ItemCatalogueUI.cs b/ItemCatalogueUI.cs
index a366fa5..8fe9d0f 100644
--- a/ItemCatalogueUI.cs
+++ b/ItemCatalogueUI.cs
@@ -217,6 +217,10 @@ private void UnobtainedRadioButton_OnSelectedChanged(object sender, EventArgs e)
updateNeeded = true;
}
+ ///
+ /// Validates the item-name filter against all item slots.
+ /// If no match is found, removes the last character and triggers a blink to indicate invalid input.
+ ///
private void ValidateItemFilter()
{
if (itemNameFilter.currentString.Length > 0)
@@ -233,13 +237,38 @@ private void ValidateItemFilter()
if (!found)
{
itemNameFilter.SetText(itemNameFilter.currentString.Substring(0, itemNameFilter.currentString.Length - 1));
+ itemNameFilter.TriggerInvalidBlink();
}
}
updateNeeded = true;
}
+ ///
+ /// Validates the item-description filter against all item slot tooltips.
+ /// If no match is found, removes the last character and triggers a blink to indicate invalid input.
+ ///
private void ValidateItemDescription()
{
+ if (itemDescriptionFilter.currentString.Length > 0)
+ {
+ bool found = false;
+
+ foreach (var itemSlot in itemSlots)
+ {
+ if (itemSlot.item.ToolTip != null && GetTooltipsAsString(itemSlot.item.ToolTip).IndexOf(itemDescriptionFilter.currentString, StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ itemDescriptionFilter.SetText(itemDescriptionFilter.currentString.Substring(0, itemDescriptionFilter.currentString.Length - 1));
+ itemDescriptionFilter.TriggerInvalidBlink();
+ }
+ }
+
updateNeeded = true;
}
@@ -519,4 +548,4 @@ public override void RecalculateChildren()
base.RecalculateChildren();
}
}
-}
\ No newline at end of file
+}
diff --git a/RecipeCatalogueUI.cs b/RecipeCatalogueUI.cs
index c11ebae..dad0ccd 100644
--- a/RecipeCatalogueUI.cs
+++ b/RecipeCatalogueUI.cs
@@ -878,7 +878,8 @@ private void ItemChecklistFilter_SelectedChanged(object sender, EventArgs e)
}
///
- /// Checks text to verify input is in
+ /// Validates the item-name filter against recipe outputs.
+ /// If no match is found, removes the last character and triggers a blink to indicate invalid input.
///
private void ValidateItemFilter()
{
@@ -897,30 +898,39 @@ private void ValidateItemFilter()
if (!found)
{
itemNameFilter.SetText(itemNameFilter.currentString.Substring(0, itemNameFilter.currentString.Length - 1));
+ itemNameFilter.TriggerInvalidBlink();
}
}
updateNeeded = true;
}
+ ///
+ /// Validates the item-description filter against recipe tooltips.
+ /// If no match is found, removes the last character and triggers a blink to indicate invalid input.
+ ///
private void ValidateItemDescription()
{
- //if (itemNameFilter.Text.Length > 0)
- //{
- // bool found = false;
- // for (int i = 0; i < Recipe.numRecipes; i++)
- // {
- // Recipe recipe = Main.recipe[i];
- // if (recipe.createItem.name.ToLower().IndexOf(itemNameFilter.Text, StringComparison.OrdinalIgnoreCase) == -1)
- // {
- // found = true;
- // break;
- // }
- // }
- // if (!found)
- // {
- // itemNameFilter.SetText(itemNameFilter.Text.Substring(0, itemNameFilter.Text.Length - 1));
- // }
- //}
+ if (itemDescriptionFilter.currentString.Length > 0)
+ {
+ bool found = false;
+
+ for (int i = 0; i < Recipe.numRecipes; i++)
+ {
+ Recipe recipe = Main.recipe[i];
+ if (recipe.createItem.ToolTip != null && GetTooltipsAsString(recipe.createItem.ToolTip).IndexOf(itemDescriptionFilter.currentString, StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ itemDescriptionFilter.SetText(itemDescriptionFilter.currentString.Substring(0, itemDescriptionFilter.currentString.Length - 1));
+ itemDescriptionFilter.TriggerInvalidBlink();
+ }
+ }
+
updateNeeded = true;
}
@@ -948,4 +958,4 @@ internal void InvalidateExtendedCraft()
SharedUI.instance.ObtainableFilter.button.LeftClick(new UIMouseEvent(null, Vector2.Zero));
}
}
-}
\ No newline at end of file
+}
diff --git a/UIElements/NewUITextBox.cs b/UIElements/NewUITextBox.cs
index 205e67f..e4df24d 100644
--- a/UIElements/NewUITextBox.cs
+++ b/UIElements/NewUITextBox.cs
@@ -25,6 +25,15 @@ internal class NewUITextBox : UIPanel//UITextPanel
private int textBlinkerCount;
private int textBlinkerState;
+ private const int BlinkIntervalFrames = 20; // frames between blink state changes
+ private const int TotalBlinks = 4; // 4 state changes = 2 full blinks
+ private int _remainingBlinkSteps; // remaining blink state changes
+ private int _blinkTimer; // frame countdown until next state change
+ private bool _blinkState; // true when currently in blink state
+
+ private readonly Color _defaultBorderColor;
+ private readonly Color _defaultBackgroundColor;
+
public event Action OnFocus;
public event Action OnUnfocus;
@@ -48,6 +57,8 @@ public NewUITextBox(string hintText, string text = "")
SetPadding(0);
BackgroundColor = Color.White;
BorderColor = Color.White;
+ _defaultBackgroundColor = BackgroundColor;
+ _defaultBorderColor = BorderColor;
// keyBoardInput.newKeyEvent += KeyboardInput_newKeyEvent;
var closeButton = new UIHoverImageButton(CloseButtonTexture, "");
@@ -206,10 +217,40 @@ private static bool JustPressed(Keys key)
return Main.inputText.IsKeyDown(key) && !Main.oldInputText.IsKeyDown(key);
}
+ ///
+ /// Triggers the blink animation when the filter yields no matches.
+ ///
+ public void TriggerInvalidBlink()
+ {
+ _remainingBlinkSteps = TotalBlinks;
+ _blinkTimer = BlinkIntervalFrames;
+ _blinkState = true;
+ }
+
protected override void DrawSelf(SpriteBatch spriteBatch)
{
Rectangle hitbox = GetInnerDimensions().ToRectangle();
+ // handle blink timing and state
+ if (_remainingBlinkSteps > 0)
+ {
+ _blinkTimer--;
+ if (_blinkTimer <= 0)
+ {
+ _blinkTimer = BlinkIntervalFrames;
+ _blinkState = !_blinkState;
+ _remainingBlinkSteps--;
+ }
+ }
+
+ // apply blink colors if active, otherwise use defaults
+ BorderColor = (_remainingBlinkSteps > 0 && _blinkState)
+ ? new Color(255, 0, 0)
+ : _defaultBorderColor;
+ BackgroundColor = (_remainingBlinkSteps > 0 && _blinkState)
+ ? new Color(255, 107, 107)
+ : _defaultBackgroundColor;
+
// Draw panel
base.DrawSelf(spriteBatch);
// Main.spriteBatch.Draw(Main.magicPixel, hitbox, Color.Yellow);
@@ -331,4 +372,4 @@ protected override void DrawSelf(SpriteBatch spriteBatch)
// Utils.DrawBorderString(spriteBatch, "|", pos, base.TextColor, base.TextScale, 0f, 0f, -1);
}
}
-}
\ No newline at end of file
+}