diff --git a/ProjectObsidian/Components/Common UI/Button Interactions/ButtonAttachComponent.cs b/ProjectObsidian/Components/Common UI/Button Interactions/ButtonAttachComponent.cs new file mode 100644 index 0000000..fc6e8af --- /dev/null +++ b/ProjectObsidian/Components/Common UI/Button Interactions/ButtonAttachComponent.cs @@ -0,0 +1,43 @@ +using System; +using FrooxEngine; +using FrooxEngine.Undo; + +namespace Obsidian; + +[Category(new string[] { "Obsidian/Common UI/Button Interactions" })] +public class ButtonAttachComponent : Component, IButtonPressReceiver, IComponent, IComponentBase, IDestroyable, IWorker, IWorldElement, IUpdatable, IChangeable, IAudioUpdatable, IInitializable, ILinkable +{ + public readonly SyncRef TargetSlot; + + public readonly SyncType ComponentType; + + public readonly Sync Undoable; + + protected override void OnAttach() + { + base.OnAwake(); + Undoable.Value = true; + } + + public void Pressed(IButton button, ButtonEventData eventData) + { + Slot target = TargetSlot.Target; + Type componentType = ComponentType.Value; + if (target != null && componentType != null && componentType.ContainsGenericParameters == false) + { + var comp = target.AttachComponent(componentType); + if (Undoable) + { + comp.CreateSpawnUndoPoint(); + } + } + } + + public void Pressing(IButton button, ButtonEventData eventData) + { + } + + public void Released(IButton button, ButtonEventData eventData) + { + } +} \ No newline at end of file diff --git a/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs b/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs index e2a7e1f..8948db9 100644 --- a/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs +++ b/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs @@ -7,6 +7,14 @@ namespace Obsidian; +// This feed has two functions. + +// If TargetSlot has a reference, it returns the components on that slot, optionally also returning components on children slots (IncludeChildrenSlots bool) +// It also returns the sync members (fields, lists etc) as DataFeedEntity + +// If TargetSlot is null, it returns the components from the component library, which includes the categories (DataFeedCategoryItem) +// When enumerating the component library, the Component reference on the ComponentDataItemInterface will be null and there will be no members + [Category(new string[] { "Obsidian/Radiant UI/Data Feeds/Feeds" })] public class ComponentsDataFeed : Component, IDataFeedComponent, IDataFeed, IWorldElement { @@ -27,7 +35,7 @@ private static bool SearchStringValid(string str) return !string.IsNullOrWhiteSpace(str) && str.Length >= 3; } - private void AddComponent(Component c) + private void OnSlotComponentAdded(Component c) { // If local elements are written to synced fields it can cause exceptions and crashes if (c.IsLocalElement) return; @@ -45,7 +53,7 @@ private void AddComponent(Component c) } } - private void RemoveComponent(Component c) + private void OnSlotComponentRemoved(Component c) { foreach (KeyValuePair updateHandler in _updateHandlers) { @@ -102,14 +110,14 @@ private void ProcessUpdate(SearchPhraseFeedUpdateHandler handler, ComponentData private void Subscribe(Slot s) { - s.ComponentAdded += AddComponent; - s.ComponentRemoved += RemoveComponent; + s.ComponentAdded += OnSlotComponentAdded; + s.ComponentRemoved += OnSlotComponentRemoved; } private void Unsubscribe(Slot s) { - s.ComponentAdded -= AddComponent; - s.ComponentRemoved -= RemoveComponent; + s.ComponentAdded -= OnSlotComponentAdded; + s.ComponentRemoved -= OnSlotComponentRemoved; } protected override void OnAwake() @@ -205,10 +213,16 @@ private IEnumerable EnumerateAllTypes(CategoryNode categoryNode) } } + private string GetCategoryKey(CategoryNode categoryNode) + { + return categoryNode.Name; + } + private DataFeedCategory GenerateCategory(string key, IReadOnlyList path) { DataFeedCategory dataFeedCategory = new DataFeedCategory(); - dataFeedCategory.InitBase(key, path, null, ("Category." + key).AsLocaleKey(), OfficialAssets.Graphics.Icons.Gizmo.TransformLocal); + // random icon + dataFeedCategory.InitBase(key, path, null, key, OfficialAssets.Graphics.Icons.Gizmo.TransformLocal); return dataFeedCategory; } @@ -218,10 +232,6 @@ public async IAsyncEnumerable Enumerate(IReadOnlyList path { yield break; } - //if (TargetSlot.Target == null && (path == null || path.Count == 0) && !SearchStringValid(searchPhrase)) - //{ - // yield break; - //} if (groupKeys != null && groupKeys.Count > 0) { yield break; @@ -251,7 +261,7 @@ public async IAsyncEnumerable Enumerate(IReadOnlyList path } foreach (var subCat2 in catNode.Subcategories) { - yield return GenerateCategory(subCat2.Name, path); + yield return GenerateCategory(GetCategoryKey(subCat2), path); } if (SearchStringValid(searchPhrase)) { @@ -276,7 +286,7 @@ public async IAsyncEnumerable Enumerate(IReadOnlyList path } foreach (var subCat in lib.Subcategories) { - yield return GenerateCategory(subCat.Name, path); + yield return GenerateCategory(GetCategoryKey(subCat), path); } if (SearchStringValid(searchPhrase)) {