Skip to content

Commit

Permalink
Merge pull request #156 from brunomikoski/feature/qol-asset-manipulation
Browse files Browse the repository at this point in the history
Feature/qol asset manipulation
  • Loading branch information
brunomikoski authored Sep 3, 2024
2 parents d91f267 + b163350 commit c857648
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 29 deletions.
9 changes: 7 additions & 2 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ 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).

## [Unreleased]
## [2.3.6]
## Changed
- Updated ListView to allow for multiple selection
- Updated Context Menu functionality to support multiple selection (Copy/Paste/Duplicate/Delete)

## [2.3.5]
## Changed
- Added `ApplyModifiedProperties()` to property drawers again, since was causing issues with the shareable picker. This was removed on [2.3.4]


## [2.3.4]
## Changed
- Update PickerPropertyDrawer to use PopupList from property path cache to avoid issue when rendered inside a List/Array
Expand Down Expand Up @@ -587,7 +591,8 @@ public bool IsValidConsumable(Consumable consumable)
### Added
- First initial working version

[2.3.5]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.3.5~~~~
[2.3.6]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.3.6
[2.3.5]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.3.5
[2.3.4]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.3.4
[2.3.3]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.3.3
[2.3.2]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.3.2
Expand Down
2 changes: 1 addition & 1 deletion Editor/UXML/CollectionCustomEditorTreeAsset.uxml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<AttributeOverrides element-name="Label" text="Items" />
<uie:ToolbarSearchField name="ToolbarSearchField" style="width: auto; margin-left: 0; margin-right: 0; margin-top: 0; margin-bottom: 0; padding-bottom: 0; top: -18px; left: 200px; right: 30px; position: absolute;" />
<ui:Button parse-escape-sequences="true" display-tooltip-when-elided="true" name="expand-button" tooltip="Expand / Collapse Items" text="▸◂" enable-rich-text="false" style="width: 18px; height: 18px; position: absolute; right: 0; top: -20px;" />
<ui:ListView virtualization-method="DynamicHeight" show-border="false" show-alternating-row-backgrounds="All" reorderable="true" show-foldout-header="false" header-title="Items" show-add-remove-footer="false" reorder-mode="Animated" show-bound-collection-size="false" name="items-list-view" horizontal-scrolling="false" selection-type="Single" view-data-key="collection-item-list-view" style="display: flex;" />
<ui:ListView virtualization-method="DynamicHeight" show-border="false" show-alternating-row-backgrounds="All" reorderable="true" show-foldout-header="false" header-title="Items" show-add-remove-footer="false" reorder-mode="Animated" show-bound-collection-size="false" name="items-list-view" horizontal-scrolling="false" selection-type="Multiple" view-data-key="collection-item-list-view" style="display: flex;" />
</ui:Instance>
<ui:VisualElement name="unity-list-view__footer" class="unity-list-view__footer">
<ui:Button name="unity-list-view__remove-button" text="-" class="unity-text-element unity-button" />
Expand Down
169 changes: 144 additions & 25 deletions Scripts/Editor/CustomEditors/CollectionCustomEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

namespace BrunoMikoski.ScriptableObjectCollections
{

[CustomEditor(typeof(ScriptableObjectCollection), true)]
public class CollectionCustomEditor : Editor
{
Expand Down Expand Up @@ -290,9 +291,9 @@ private void BindCollectionItemListItem(VisualElement targetElement, int targetI
Editor editor = EditorCache.GetOrCreateEditorForObject(targetItem);

Label titleLabel = foldout.Q<Label>();
titleLabel.RegisterCallback<MouseDownEvent, int>(RenameItemAtIndex, targetIndex);
titleLabel.RegisterCallback<MouseDownEvent, int>(RenameItemAtIndex, targetIndex, TrickleDown.TrickleDown);

targetElement.RegisterCallback<MouseUpEvent, int>(ShowOptionsForIndex, targetIndex);
targetElement.parent.parent.RegisterCallback<MouseUpEvent, int>(ShowOptionsForIndex, targetIndex);

imguiContainer.onGUIHandler = () =>
{
Expand Down Expand Up @@ -435,15 +436,35 @@ private void OnClickGenerateStaticFile(MouseUpEvent evt)

private void OnClickRemoveSelectedItems(MouseUpEvent evt)
{


if (!collectionItemListView.selectedIndices.Any())
{
if (!EditorUtility.DisplayDialog($"Delete Item",
$"Are you sure you want to delete {filteredItems[^1].name}?", "Yes", "No"))
{
return;
}

DeleteItemAtIndex(filteredItems.Count - 1);
}
else
{
if (!EditorUtility.DisplayDialog($"Delete {collectionItemListView.selectedIndices.Count()} Items",
$"Are you sure you want to delete all {collectionItemListView.selectedIndices.Count()} items?", "Yes", "No"))
{
return;
}

List<ScriptableObject> itemsToBeDuplicated = new List<ScriptableObject>();
foreach (int selectedIndex in collectionItemListView.selectedIndices)
{
DeleteItemAtIndex(selectedIndex);
itemsToBeDuplicated.Add(filteredItems[selectedIndex]);
}

foreach (ScriptableObject item in itemsToBeDuplicated)
{
DeleteItemAtIndex(collection.IndexOf(item));
}
}

Expand Down Expand Up @@ -657,12 +678,6 @@ protected void DeleteItemAtIndex(int selectedIndex)
return;
}

if (!EditorUtility.DisplayDialog($"Delete {scriptableObject.name}",
$"Are you sure you want to delete {scriptableObject.name}?", "Yes", "No"))
{
return;
}

Undo.RecordObject(collection, "Remove Item");

filteredItems.Remove(scriptableObject);
Expand Down Expand Up @@ -696,22 +711,47 @@ private void ShowOptionsForIndex(MouseUpEvent evt, int targetIndex)
{
if (evt.button != 1)
return;


int selectedItemsCount = collectionItemListView.selectedIndices.Count();
bool singleItemSelected = selectedItemsCount == 1;

ScriptableObject scriptableObject = filteredItems[targetIndex];

GenericMenu menu = new GenericMenu();

menu.AddItem(
new GUIContent("Copy Values"),
false,
() => { CopyCollectionItemUtility.SetSource(scriptableObject); }
);
if (singleItemSelected)
{
menu.AddItem(
new GUIContent("Copy Values"),
false,
() => { CopyCollectionItemUtility.SetSource(scriptableObject); }
);
}
else
{
menu.AddDisabledItem(
new GUIContent("Copy Values"),
false);
}
if (CopyCollectionItemUtility.CanPasteToTarget(scriptableObject))
{
menu.AddItem(
new GUIContent("Paste Values"),
false,
() => { CopyCollectionItemUtility.ApplySourceToTarget(scriptableObject); }
() =>
{
if (selectedItemsCount > 0)
{
foreach (int selectedIndex in collectionItemListView.selectedIndices)
{
CopyCollectionItemUtility.ApplySourceToTarget(filteredItems[selectedIndex]);
}
}
else
{
CopyCollectionItemUtility.ApplySourceToTarget(scriptableObject);
}
}
);
}
else
Expand All @@ -724,39 +764,118 @@ private void ShowOptionsForIndex(MouseUpEvent evt, int targetIndex)
menu.AddItem(
new GUIContent("Duplicate Item"),
false,
() => { DuplicateItem(targetIndex); }
() =>
{
if (selectedItemsCount > 0)
{
List<ScriptableObject> itemsToBeDuplicated = new List<ScriptableObject>();
foreach (int selectedIndex in collectionItemListView.selectedIndices)
{
itemsToBeDuplicated.Add(filteredItems[selectedIndex]);
}

foreach (ScriptableObject item in itemsToBeDuplicated)
{
DuplicateItem(item, false);
}
}
else
{
DuplicateItem(targetIndex);
}
}
);

menu.AddItem(
new GUIContent("Delete Item"),
false,
() => { DeleteItemAtIndex(targetIndex); }
() =>
{
if (selectedItemsCount > 0)
{
if (!EditorUtility.DisplayDialog($"Delete {collectionItemListView.selectedIndices.Count()} Items",
$"Are you sure you want to delete all {collectionItemListView.selectedIndices.Count()} items?", "Yes", "No"))
{
return;
}

List<ScriptableObject> itemsToBeDuplicated = new List<ScriptableObject>();
foreach (int selectedIndex in collectionItemListView.selectedIndices)
{
itemsToBeDuplicated.Add(filteredItems[selectedIndex]);
}

foreach (ScriptableObject item in itemsToBeDuplicated)
{
DeleteItemAtIndex(collection.IndexOf(item));
}
}
else
{
if (!EditorUtility.DisplayDialog($"Delete Item",
$"Are you sure you want to delete {filteredItems[^1].name}?", "Yes", "No"))
{
return;
}

DeleteItemAtIndex(targetIndex);
}
}
);

menu.AddSeparator("");
menu.AddItem(
new GUIContent("Select Asset"),
false,
() => { SelectItemAtIndex(targetIndex); }
() =>
{
if (selectedItemsCount > 0)
{
SelectItemAtIndex(collectionItemListView.selectedIndices.ToArray());
}
else
{
SelectItemAtIndex(targetIndex);
}
}
);

menu.ShowAsContext();
}

private void SelectItemAtIndex(int index)
private void SelectItemAtIndex(params int[] index)
{
ScriptableObject collectionItem = filteredItems[index];
Selection.objects = new Object[] { collectionItem };
Object[] selectedObjects = new Object[index.Length];
for (int i = 0; i < index.Length; i++)
{
selectedObjects[i] = filteredItems[index[i]];
}
Selection.objects = selectedObjects;
}

private void DuplicateItem(int index)
private void DuplicateItem(int index, bool showRenameAfter = true)
{
ScriptableObject source = filteredItems[index];
DuplicateItem(source, showRenameAfter);
}

private void DuplicateItem(ScriptableObject source, bool showRenameAfter)
{
CopyCollectionItemUtility.SetSource(source);
ScriptableObject newItem = AddNewItemOfType(source.GetType(), false);
CopyCollectionItemUtility.ApplySourceToTarget(newItem);
int targetIndex = filteredItems.IndexOf(newItem);
RenameItemAtIndex(targetIndex);

if (showRenameAfter)
{
int targetIndex = filteredItems.IndexOf(newItem);
RenameItemAtIndex(targetIndex);
}
else
{
AssetDatabaseUtils.RenameAsset(newItem, $"{source.name} (Copy)");
AssetDatabase.SaveAssetIfDirty(newItem);
ReloadFilteredItems();
}
}

private void RenameItemAtIndex(MouseDownEvent evt, int targetIndex)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "com.brunomikoski.scriptableobjectcollection",
"displayName": "Scriptable Object Collection",
"version": "2.3.4",
"version": "2.3.6",
"unity": "2022.2",
"description": "A library to help improve the usability of Unity3D Scriptable Objects by grouping them into a collection and exposing them by code or nice inspectors!",
"keywords": [
Expand Down

0 comments on commit c857648

Please sign in to comment.