fixed that fucking ui problem!!! thank you kas <3
This commit is contained in:
parent
9f1ebe05a1
commit
d39e6895af
10 changed files with 2786 additions and 163 deletions
137
Assets/Resources/Materials/New Material.mat
Normal file
137
Assets/Resources/Materials/New Material.mat
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &-6002683583417286212
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 11
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
version: 10
|
||||||
|
--- !u!21 &2100000
|
||||||
|
Material:
|
||||||
|
serializedVersion: 8
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: New Material
|
||||||
|
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
|
||||||
|
m_Parent: {fileID: 0}
|
||||||
|
m_ModifiedSerializedProperties: 0
|
||||||
|
m_ValidKeywords: []
|
||||||
|
m_InvalidKeywords: []
|
||||||
|
m_LightmapFlags: 4
|
||||||
|
m_EnableInstancingVariants: 0
|
||||||
|
m_DoubleSidedGI: 0
|
||||||
|
m_CustomRenderQueue: -1
|
||||||
|
stringTagMap:
|
||||||
|
RenderType: Opaque
|
||||||
|
disabledShaderPasses:
|
||||||
|
- MOTIONVECTORS
|
||||||
|
m_LockedProperties:
|
||||||
|
m_SavedProperties:
|
||||||
|
serializedVersion: 3
|
||||||
|
m_TexEnvs:
|
||||||
|
- _BaseMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _BumpMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _DetailAlbedoMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _DetailMask:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _DetailNormalMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _EmissionMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _MainTex:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _MetallicGlossMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _OcclusionMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _ParallaxMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _SpecGlossMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- unity_Lightmaps:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- unity_LightmapsInd:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- unity_ShadowMasks:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
m_Ints: []
|
||||||
|
m_Floats:
|
||||||
|
- _AddPrecomputedVelocity: 0
|
||||||
|
- _AlphaClip: 0
|
||||||
|
- _AlphaToMask: 0
|
||||||
|
- _Blend: 0
|
||||||
|
- _BlendModePreserveSpecular: 1
|
||||||
|
- _BumpScale: 1
|
||||||
|
- _ClearCoatMask: 0
|
||||||
|
- _ClearCoatSmoothness: 0
|
||||||
|
- _Cull: 2
|
||||||
|
- _Cutoff: 0.5
|
||||||
|
- _DetailAlbedoMapScale: 1
|
||||||
|
- _DetailNormalMapScale: 1
|
||||||
|
- _DstBlend: 0
|
||||||
|
- _DstBlendAlpha: 0
|
||||||
|
- _EnvironmentReflections: 1
|
||||||
|
- _GlossMapScale: 0
|
||||||
|
- _Glossiness: 0
|
||||||
|
- _GlossyReflections: 0
|
||||||
|
- _Metallic: 0
|
||||||
|
- _OcclusionStrength: 1
|
||||||
|
- _Parallax: 0.005
|
||||||
|
- _QueueOffset: 0
|
||||||
|
- _ReceiveShadows: 1
|
||||||
|
- _Smoothness: 0.5
|
||||||
|
- _SmoothnessTextureChannel: 0
|
||||||
|
- _SpecularHighlights: 1
|
||||||
|
- _SrcBlend: 1
|
||||||
|
- _SrcBlendAlpha: 1
|
||||||
|
- _Surface: 0
|
||||||
|
- _WorkflowMode: 1
|
||||||
|
- _XRMotionVectorsPass: 1
|
||||||
|
- _ZWrite: 1
|
||||||
|
m_Colors:
|
||||||
|
- _BaseColor: {r: 1, g: 0, b: 0, a: 1}
|
||||||
|
- _Color: {r: 1, g: 0, b: 0, a: 1}
|
||||||
|
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||||
|
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
|
||||||
|
m_BuildTextureStacks: []
|
||||||
|
m_AllowLocking: 1
|
8
Assets/Resources/Materials/New Material.mat.meta
Normal file
8
Assets/Resources/Materials/New Material.mat.meta
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 63b9ee8d7c472fcdd9d64669d3d96daf
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 2100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -14,6 +14,6 @@ MonoBehaviour:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
Description:
|
Description:
|
||||||
value:
|
value:
|
||||||
value: 0
|
value: -50
|
||||||
clamp: 1
|
clamp: 1
|
||||||
minMax: {x: -50, y: 10}
|
minMax: {x: -50, y: 10}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Linq;
|
||||||
using KitsuneCafe.Sys;
|
using KitsuneCafe.Sys;
|
||||||
using ObservableCollections;
|
using ObservableCollections;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
@ -92,11 +94,14 @@ namespace KitsuneCafe.ItemSystem
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private int capacity = 8;
|
private int capacity = 8;
|
||||||
|
|
||||||
|
public event NotifyCollectionChangedEventHandler<InventoryItem> CollectionChanged;
|
||||||
|
|
||||||
public int Capacity => capacity;
|
public int Capacity => capacity;
|
||||||
|
|
||||||
public int Count => items.Count;
|
public int Count => items.Count;
|
||||||
|
|
||||||
public bool IsEmpty => Count == 0;
|
public bool IsEmpty => Count == 0;
|
||||||
|
|
||||||
public bool IsFull => Count == Capacity;
|
public bool IsFull => Count == Capacity;
|
||||||
|
|
||||||
public object SyncRoot => ((IList)items).SyncRoot;
|
public object SyncRoot => ((IList)items).SyncRoot;
|
||||||
|
@ -107,7 +112,11 @@ namespace KitsuneCafe.ItemSystem
|
||||||
|
|
||||||
public bool IsSynchronized => ((ICollection)items).IsSynchronized;
|
public bool IsSynchronized => ((ICollection)items).IsSynchronized;
|
||||||
|
|
||||||
object IList.this[int index] { get => items[index]; set => items[index] = (InventoryItem)value; }
|
object IList.this[int index]
|
||||||
|
{
|
||||||
|
get => items[index];
|
||||||
|
set => items[index] = (InventoryItem)value;
|
||||||
|
}
|
||||||
|
|
||||||
public InventoryItem this[int index]
|
public InventoryItem this[int index]
|
||||||
{
|
{
|
||||||
|
@ -115,6 +124,7 @@ namespace KitsuneCafe.ItemSystem
|
||||||
set => items[index] = value;
|
set => items[index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IEnumerable<InventoryItem> Find(Func<InventoryItem, bool> predicate)
|
public IEnumerable<InventoryItem> Find(Func<InventoryItem, bool> predicate)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Count; i++)
|
for (int i = 0; i < Count; i++)
|
||||||
|
@ -135,9 +145,12 @@ namespace KitsuneCafe.ItemSystem
|
||||||
return Result.Err<int, InventoryError>(InventoryError.InvalidQuantity);
|
return Result.Err<int, InventoryError>(InventoryError.InvalidQuantity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<InventoryItem> existing = new();
|
||||||
|
List<InventoryItem> updated = new();
|
||||||
for (int i = 0; i < Count; i++)
|
for (int i = 0; i < Count; i++)
|
||||||
{
|
{
|
||||||
var existingItem = items[i];
|
var existingItem = items[i];
|
||||||
|
existing.Add(existingItem);
|
||||||
|
|
||||||
if (existingItem.Equals(item))
|
if (existingItem.Equals(item))
|
||||||
{
|
{
|
||||||
|
@ -147,6 +160,7 @@ namespace KitsuneCafe.ItemSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
var consumedAmount = existingItem.IncreaseCount(count, out var updatedItem);
|
var consumedAmount = existingItem.IncreaseCount(count, out var updatedItem);
|
||||||
|
updated.Add(updatedItem.Value);
|
||||||
items[i] = updatedItem.Value;
|
items[i] = updatedItem.Value;
|
||||||
|
|
||||||
count -= consumedAmount;
|
count -= consumedAmount;
|
||||||
|
@ -157,11 +171,13 @@ namespace KitsuneCafe.ItemSystem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Notify(NotifyCollectionChangedAction.Replace, updated, existing);
|
||||||
return Result.Ok<int, InventoryError>(count);
|
return Result.Ok<int, InventoryError>(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IResult<Unit, InventoryError> AddNew(Item item, int count)
|
private IResult<Unit, InventoryError> AddNew(Item item, int count)
|
||||||
{
|
{
|
||||||
|
List<InventoryItem> added = new();
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
{
|
{
|
||||||
if (IsFull)
|
if (IsFull)
|
||||||
|
@ -171,9 +187,10 @@ namespace KitsuneCafe.ItemSystem
|
||||||
|
|
||||||
count -= InventoryItem.Create(item, count, out var newItem);
|
count -= InventoryItem.Create(item, count, out var newItem);
|
||||||
items.Add(newItem.Value);
|
items.Add(newItem.Value);
|
||||||
|
added.Add(newItem.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Notify(NotifyCollectionChangedAction.Add, added);
|
||||||
return Result.Ok<Unit, InventoryError>(default);
|
return Result.Ok<Unit, InventoryError>(default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,6 +206,32 @@ namespace KitsuneCafe.ItemSystem
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Notify(NotifyCollectionChangedAction action, IList<InventoryItem> newItems = default, IList<InventoryItem> oldItems = default)
|
||||||
|
{
|
||||||
|
NotifyCollectionChangedEventArgs<InventoryItem> args;
|
||||||
|
|
||||||
|
if (newItems.Count == 1)
|
||||||
|
{
|
||||||
|
args = new(
|
||||||
|
action,
|
||||||
|
true,
|
||||||
|
newItems[0],
|
||||||
|
oldItems[0]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
args = new(
|
||||||
|
action,
|
||||||
|
false,
|
||||||
|
newItems: newItems.ToArray(),
|
||||||
|
oldItems: oldItems.ToArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
CollectionChanged?.Invoke(args);
|
||||||
|
}
|
||||||
|
|
||||||
public IResult<Unit, InventoryError> Remove(Item item, int count = 1)
|
public IResult<Unit, InventoryError> Remove(Item item, int count = 1)
|
||||||
{
|
{
|
||||||
if (count <= 0)
|
if (count <= 0)
|
||||||
|
@ -196,6 +239,8 @@ namespace KitsuneCafe.ItemSystem
|
||||||
return Result.Err<Unit, InventoryError>(InventoryError.InvalidQuantity);
|
return Result.Err<Unit, InventoryError>(InventoryError.InvalidQuantity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<InventoryItem> removed = new();
|
||||||
|
List<InventoryItem> updated = new();
|
||||||
for (int i = items.Count - 1; i >= 0; i--)
|
for (int i = items.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
var existingItem = items[i];
|
var existingItem = items[i];
|
||||||
|
@ -206,15 +251,22 @@ namespace KitsuneCafe.ItemSystem
|
||||||
{
|
{
|
||||||
existingItem.ReduceCount(count, out var updatedItem);
|
existingItem.ReduceCount(count, out var updatedItem);
|
||||||
items[i] = updatedItem.Value;
|
items[i] = updatedItem.Value;
|
||||||
|
|
||||||
|
removed.Add(existingItem);
|
||||||
|
updated.Add(updatedItem.Value);
|
||||||
|
|
||||||
|
Notify(NotifyCollectionChangedAction.Remove, updated, removed);
|
||||||
return Result.Ok<Unit, InventoryError>(Unit.Default);
|
return Result.Ok<Unit, InventoryError>(Unit.Default);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
count -= existingItem.Count;
|
count -= existingItem.Count;
|
||||||
items.RemoveAt(i);
|
items.RemoveAt(i);
|
||||||
|
removed.Add(existingItem);
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
{
|
{
|
||||||
|
Notify(NotifyCollectionChangedAction.Remove, updated, removed);
|
||||||
return Result.Ok<Unit, InventoryError>(Unit.Default);
|
return Result.Ok<Unit, InventoryError>(Unit.Default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,6 +278,7 @@ namespace KitsuneCafe.ItemSystem
|
||||||
return Result.Err<Unit, InventoryError>(InventoryError.NotEnoughQuantity);
|
return Result.Err<Unit, InventoryError>(InventoryError.NotEnoughQuantity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Notify(NotifyCollectionChangedAction.Remove, updated, removed);
|
||||||
return Result.Ok<Unit, InventoryError>(Unit.Default);
|
return Result.Ok<Unit, InventoryError>(Unit.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,5 +344,71 @@ namespace KitsuneCafe.ItemSystem
|
||||||
{
|
{
|
||||||
((ICollection)items).CopyTo(array, index);
|
((ICollection)items).CopyTo(array, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public ISynchronizedView<InventoryItem, TView> CreateView<TView>(Func<InventoryItem, TView> transform)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InventoryView<TView> : ISynchronizedView<InventoryItem, TView>
|
||||||
|
{
|
||||||
|
private Inventory inventory;
|
||||||
|
|
||||||
|
public object SyncRoot => inventory.SyncRoot;
|
||||||
|
|
||||||
|
private ISynchronizedViewFilter<InventoryItem, TView> filter;
|
||||||
|
public ISynchronizedViewFilter<InventoryItem, TView> Filter => filter;
|
||||||
|
|
||||||
|
public IEnumerable<(InventoryItem Value, TView View)> Filtered => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public IEnumerable<(InventoryItem Value, TView View)> Unfiltered => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public int UnfilteredCount => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public int Count => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public event NotifyViewChangedEventHandler<InventoryItem, TView> ViewChanged;
|
||||||
|
public event Action<RejectedViewChangedAction, int, int> RejectedViewChanged;
|
||||||
|
public event Action<NotifyCollectionChangedAction> CollectionStateChanged;
|
||||||
|
|
||||||
|
public void AttachFilter(ISynchronizedViewFilter<InventoryItem, TView> filter)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<TView> GetEnumerator()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetFilter()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher collectionEventDispatcher)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ISynchronizedViewList<TView> ToViewList()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace KitsuneCafe.UI
|
||||||
{
|
{
|
||||||
public class RecyclerViewModel
|
public class RecyclerViewModel
|
||||||
{
|
{
|
||||||
public record RotateEvent(Direction Direction, int FirstIndex);
|
public record RotateEvent(Direction Direction, int FirstIndex, object CurrentItem);
|
||||||
|
|
||||||
public enum Direction
|
public enum Direction
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,6 @@ namespace KitsuneCafe.UI
|
||||||
if (displayCount != value)
|
if (displayCount != value)
|
||||||
{
|
{
|
||||||
displayCount = value;
|
displayCount = value;
|
||||||
CreateIndices();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,15 +42,14 @@ namespace KitsuneCafe.UI
|
||||||
if (itemSource != value)
|
if (itemSource != value)
|
||||||
{
|
{
|
||||||
itemSource = value;
|
itemSource = value;
|
||||||
CreateIndices();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Count => Math.Min(DisplayCount, ItemSource.Count);
|
public int Count => Math.Max(displayCount, itemSource.Count);
|
||||||
|
|
||||||
private List<int> indices;
|
private int currentIndex = 0;
|
||||||
public IReadOnlyList<int> Indices => indices;
|
public int SelectedIndex => currentIndex;
|
||||||
|
|
||||||
public readonly ICommand<Direction> RotateCommand;
|
public readonly ICommand<Direction> RotateCommand;
|
||||||
|
|
||||||
|
@ -59,52 +57,113 @@ namespace KitsuneCafe.UI
|
||||||
|
|
||||||
public RecyclerViewModel()
|
public RecyclerViewModel()
|
||||||
{
|
{
|
||||||
indices = new();
|
|
||||||
RotateCommand = new RelayCommand<Direction>(CanRotate, Rotate);
|
RotateCommand = new RelayCommand<Direction>(CanRotate, Rotate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateIndices()
|
|
||||||
{
|
|
||||||
if (itemSource == null || displayCount == 0) { return; }
|
|
||||||
indices = Enumerable.Range(0, Math.Min(DisplayCount, ItemSource.Count)).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool CanRotate(Direction direction)
|
private bool CanRotate(Direction direction)
|
||||||
{
|
{
|
||||||
return direction == Direction.Clockwise || direction == Direction.CounterClockwise;
|
return direction == Direction.Clockwise || direction == Direction.CounterClockwise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int WrapIndex(int index, int count)
|
||||||
|
{
|
||||||
|
return (index + count) % count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int WrapIndex(int index)
|
||||||
|
{
|
||||||
|
return WrapIndex(index, Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetOffset(int index)
|
||||||
|
{
|
||||||
|
return WrapIndex(currentIndex + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T GetItem<T>(IList<T> xs, int index)
|
||||||
|
{
|
||||||
|
return xs[WrapIndex(index, xs.Count)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static object GetItem(IList xs, int index)
|
||||||
|
{
|
||||||
|
return xs[WrapIndex(index, xs.Count)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public object GetItem(int index)
|
||||||
|
{
|
||||||
|
if (0 > index || index >= itemSource.Count) { return null; }
|
||||||
|
return GetItem(itemSource, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<T> GetSlice<T>(IList<T> xs, int first, int count)
|
||||||
|
{
|
||||||
|
var diff = count - xs.Count;
|
||||||
|
var xs2 = new List<T>(xs);
|
||||||
|
xs2.AddRange(Enumerable.Repeat<T>(default, diff));
|
||||||
|
var len = first + count;
|
||||||
|
for (int i = first; i < len; i++)
|
||||||
|
{
|
||||||
|
yield return GetItem<T>(xs2, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable GetSlice(IList xs, int first, int count)
|
||||||
|
{
|
||||||
|
var diff = count - xs.Count;
|
||||||
|
var xs2 = xs.Cast<object>().ToList();
|
||||||
|
xs2.AddRange(Enumerable.Repeat<object>(default, diff));
|
||||||
|
var len = first + count;
|
||||||
|
for (int i = first; i < len; i++)
|
||||||
|
{
|
||||||
|
yield return GetItem<object>(xs2, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable GetSlice(int first, int count)
|
||||||
|
{
|
||||||
|
return GetSlice(itemSource, first, count);
|
||||||
|
}
|
||||||
|
|
||||||
public void Rotate(Direction direction)
|
public void Rotate(Direction direction)
|
||||||
{
|
{
|
||||||
if (direction == Direction.Clockwise)
|
var dir = direction switch
|
||||||
{
|
{
|
||||||
indices.RemoveAt(0);
|
Direction.Clockwise => 1,
|
||||||
var next = indices.Last() + 1;
|
Direction.CounterClockwise => -1,
|
||||||
next %= ItemSource.Count;
|
_ => 0
|
||||||
indices.Add(next);
|
};
|
||||||
Notify(direction);
|
|
||||||
}
|
|
||||||
else if (direction == Direction.CounterClockwise)
|
|
||||||
|
if (dir != 0)
|
||||||
{
|
{
|
||||||
indices.RemoveAt(ItemSource.Count - 1);
|
currentIndex = WrapIndex(currentIndex + dir);
|
||||||
var count = ItemSource.Count;
|
|
||||||
var previous = indices[0] - 1;
|
|
||||||
previous += count % count;
|
|
||||||
indices.Insert(0, previous);
|
|
||||||
Notify(direction);
|
Notify(direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Notify(Direction direction)
|
private void Notify(Direction direction)
|
||||||
{
|
{
|
||||||
Rotated?.Invoke(this, new RotateEvent(direction, indices.First()));
|
Rotated?.Invoke(this, new RotateEvent(
|
||||||
|
direction,
|
||||||
|
currentIndex,
|
||||||
|
GetItem(currentIndex)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SelectEvent : EventBase<SelectEvent>
|
public class SelectEvent : EventBase<SelectEvent>
|
||||||
{
|
{
|
||||||
public int ElementIndex { get; set; }
|
public int SelectedIndex;
|
||||||
public int DataIndex { get; set; }
|
public object SelectedItem;
|
||||||
|
|
||||||
|
protected override void Init()
|
||||||
|
{
|
||||||
|
base.Init();
|
||||||
|
bubbles = true;
|
||||||
|
tricklesDown = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[UxmlElement]
|
[UxmlElement]
|
||||||
|
@ -138,17 +197,17 @@ namespace KitsuneCafe.UI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IBinder binder;
|
private VisualTreeAsset template;
|
||||||
|
|
||||||
[CreateProperty]
|
[UxmlAttribute, CreateProperty]
|
||||||
public IBinder Binder
|
public VisualTreeAsset Template
|
||||||
{
|
{
|
||||||
get => binder;
|
get => template;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (binder != value)
|
if (template != value)
|
||||||
{
|
{
|
||||||
binder = value;
|
template = value;
|
||||||
CreateItems();
|
CreateItems();
|
||||||
Rebind();
|
Rebind();
|
||||||
}
|
}
|
||||||
|
@ -173,18 +232,20 @@ namespace KitsuneCafe.UI
|
||||||
private void CreateItems()
|
private void CreateItems()
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
if (DisplayCount == 0 || binder == null) { return; }
|
if (DisplayCount == 0 || template == null) { return; }
|
||||||
for (int i = 0; i < DisplayCount; i++)
|
for (int i = 0; i < DisplayCount; i++)
|
||||||
{
|
{
|
||||||
Add(binder.CreateItem());
|
var ve = template.CloneTree();
|
||||||
|
ve.focusable = true;
|
||||||
|
Add(ve);
|
||||||
}
|
}
|
||||||
|
|
||||||
FocusFirst();
|
FocusFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Rebind()
|
public void Rebind()
|
||||||
{
|
{
|
||||||
if (viewModel == null || ItemSource == null || DisplayCount == 0 || binder == null) { return; }
|
if (viewModel == null || ItemSource == null || DisplayCount == 0) { return; }
|
||||||
|
|
||||||
for (int i = 0; i < DisplayCount; i++)
|
for (int i = 0; i < DisplayCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -199,34 +260,35 @@ namespace KitsuneCafe.UI
|
||||||
|
|
||||||
private void OnRotated(object sender, RecyclerViewModel.RotateEvent e)
|
private void OnRotated(object sender, RecyclerViewModel.RotateEvent e)
|
||||||
{
|
{
|
||||||
VisualElement recycled;
|
var first = 0;
|
||||||
switch (e.Direction)
|
var last = DisplayCount - 1;
|
||||||
|
|
||||||
|
var (from, to) = e.Direction switch
|
||||||
{
|
{
|
||||||
case RecyclerViewModel.Direction.Clockwise:
|
RecyclerViewModel.Direction.Clockwise => (first, last),
|
||||||
recycled = this[0];
|
RecyclerViewModel.Direction.CounterClockwise => (last, first),
|
||||||
RemoveAt(0);
|
RecyclerViewModel.Direction.None => (-1, -1)
|
||||||
Insert(DisplayCount - 1, recycled);
|
};
|
||||||
TryBindItem(recycled, DisplayCount - 1);
|
|
||||||
NotifySelection();
|
if (from == -1 && to == -1) { return; }
|
||||||
break;
|
|
||||||
case RecyclerViewModel.Direction.CounterClockwise:
|
var element = this[from];
|
||||||
recycled = this[DisplayCount - 1];
|
|
||||||
RemoveAt(DisplayCount - 1);
|
RemoveAt(from);
|
||||||
Insert(0, recycled);
|
Insert(to, element);
|
||||||
TryBindItem(recycled, 0);
|
|
||||||
NotifySelection();
|
element.dataSource = viewModel.GetItem(viewModel.GetOffset(to));
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
FocusFirst();
|
FocusFirst();
|
||||||
|
NotifySelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NotifySelection()
|
private void NotifySelection()
|
||||||
{
|
{
|
||||||
using SelectEvent evt = SelectEvent.GetPooled();
|
using SelectEvent evt = SelectEvent.GetPooled();
|
||||||
evt.target = this[0];
|
evt.target = this[0];
|
||||||
evt.ElementIndex = 0;
|
evt.SelectedIndex = viewModel.SelectedIndex;
|
||||||
evt.DataIndex = viewModel.Indices[0];
|
evt.SelectedItem = viewModel.GetItem(evt.SelectedIndex);
|
||||||
SendEvent(evt);
|
SendEvent(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,15 +304,15 @@ namespace KitsuneCafe.UI
|
||||||
{
|
{
|
||||||
if (HasItem(index))
|
if (HasItem(index))
|
||||||
{
|
{
|
||||||
var idx = viewModel.Indices[index];
|
var idx = viewModel.WrapIndex(index);
|
||||||
if (0 <= idx && idx < ItemSource.Count)
|
if (0 <= idx && idx < ItemSource.Count)
|
||||||
{
|
{
|
||||||
binder.BindItem(element, idx);
|
element.dataSource = ItemSource[idx];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
binder.UnbindItem(element);
|
element.dataSource = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
using System;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using KitsuneCafe.ItemSystem;
|
using KitsuneCafe.ItemSystem;
|
||||||
using KitsuneCafe.SOAP;
|
using KitsuneCafe.SOAP;
|
||||||
using KitsuneCafe.UI.MVVM;
|
using KitsuneCafe.UI.MVVM;
|
||||||
|
using ObservableCollections;
|
||||||
using R3;
|
using R3;
|
||||||
using UnityEditor.UIElements;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UIElements;
|
using UnityEngine.UIElements;
|
||||||
|
|
||||||
|
@ -11,7 +12,7 @@ namespace KitsuneCafe.UI
|
||||||
{
|
{
|
||||||
public class InventoryScreen : MonoBehaviour
|
public class InventoryScreen : MonoBehaviour
|
||||||
{
|
{
|
||||||
public const string ItemListIndicatorsName = "item-list-indicator";
|
public const string ItemListIndicatorsName = "item-list-indicator-container";
|
||||||
public const string ItemListName = "item-list";
|
public const string ItemListName = "item-list";
|
||||||
|
|
||||||
public const string ItemPreviewName = "item-preview";
|
public const string ItemPreviewName = "item-preview";
|
||||||
|
@ -49,7 +50,8 @@ namespace KitsuneCafe.UI
|
||||||
|
|
||||||
private VisualElement root => doc.rootVisualElement;
|
private VisualElement root => doc.rootVisualElement;
|
||||||
|
|
||||||
private VisualElement indicators;
|
private List<VisualElement> indicators;
|
||||||
|
private RecyclerView itemList;
|
||||||
private VisualElement itemPreview;
|
private VisualElement itemPreview;
|
||||||
|
|
||||||
private void OnValidate()
|
private void OnValidate()
|
||||||
|
@ -92,29 +94,30 @@ namespace KitsuneCafe.UI
|
||||||
|
|
||||||
private void CreateItemList()
|
private void CreateItemList()
|
||||||
{
|
{
|
||||||
var itemList = root.Q<RecyclerView>();
|
var indicatorContainer = root.Q<VisualElement>(ItemListIndicatorsName);
|
||||||
|
indicators = indicatorContainer.Children().ToList();
|
||||||
|
|
||||||
|
itemList = root.Q<RecyclerView>();
|
||||||
itemList.ItemSource = inventory;
|
itemList.ItemSource = inventory;
|
||||||
itemList.Binder = new AdHocBinder(
|
|
||||||
() =>
|
|
||||||
{
|
|
||||||
var instance = template.CloneTree();
|
|
||||||
instance.focusable = true;
|
|
||||||
return instance;
|
|
||||||
},
|
|
||||||
(el, i) =>
|
|
||||||
{
|
|
||||||
el.dataSource = inventory[i];
|
|
||||||
},
|
|
||||||
el =>
|
|
||||||
{
|
|
||||||
el.dataSource = null;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
itemList.RegisterCallback<SelectEvent>(evt =>
|
itemList.RegisterCallback<SelectEvent>(evt =>
|
||||||
{
|
{
|
||||||
Debug.Log($"Selected {evt.DataIndex}");
|
if (evt.SelectedItem == null)
|
||||||
|
{
|
||||||
|
selectedItem.Value = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
selectedItem.Value = ((InventoryItem)evt.SelectedItem).Item;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
inventory.CollectionChanged += RebindItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RebindItems(in NotifyCollectionChangedEventArgs<InventoryItem> e)
|
||||||
|
{
|
||||||
|
itemList.Rebind();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<ui:VisualElement name="indicator-five" class="indicator" />
|
<ui:VisualElement name="indicator-five" class="indicator" />
|
||||||
<ui:VisualElement name="indicator-six" class="indicator" />
|
<ui:VisualElement name="indicator-six" class="indicator" />
|
||||||
</ui:VisualElement>
|
</ui:VisualElement>
|
||||||
<KitsuneCafe.UI.RecyclerView display-count="5" style="flex-grow: 1; flex-direction: row-reverse;" />
|
<KitsuneCafe.UI.RecyclerView display-count="5" template="project://database/Assets/UI/ItemSlot.uxml?fileID=9197481963319205126&guid=01b74a9c8f3685fb2880379892a17e46&type=3#ItemSlot" style="flex-grow: 1; flex-direction: row-reverse;" />
|
||||||
</ui:VisualElement>
|
</ui:VisualElement>
|
||||||
<ui:VisualElement name="detail-container" class="spaced-children" style="flex-grow: 1.5; flex-direction: row;">
|
<ui:VisualElement name="detail-container" class="spaced-children" style="flex-grow: 1.5; flex-direction: row;">
|
||||||
<ui:VisualElement name="condition-container" class="container" style="flex-grow: 0.65; flex-basis: 0;">
|
<ui:VisualElement name="condition-container" class="container" style="flex-grow: 0.65; flex-basis: 0;">
|
||||||
|
@ -57,16 +57,16 @@
|
||||||
<ui:VisualElement name="preview-header" class="header" />
|
<ui:VisualElement name="preview-header" class="header" />
|
||||||
<KitsuneCafe.UI.PreviewView style="background-image: url("project://database/Assets/UI/Item%20Preview.renderTexture?fileID=8400000&guid=fc19a022409ab0d408fa0e78cfeab827&type=2#Item Preview"); -unity-background-scale-mode: scale-to-fit; flex-grow: 1;" />
|
<KitsuneCafe.UI.PreviewView style="background-image: url("project://database/Assets/UI/Item%20Preview.renderTexture?fileID=8400000&guid=fc19a022409ab0d408fa0e78cfeab827&type=2#Item Preview"); -unity-background-scale-mode: scale-to-fit; flex-grow: 1;" />
|
||||||
</ui:VisualElement>
|
</ui:VisualElement>
|
||||||
<ui:VisualElement name="item-details-container" data-source="project://database/Assets/SOAP/Items/SelectedItem.asset?fileID=11400000&guid=37d00232a0bee1e8e923705187ff2187&type=2#SelectedItem" class="container" style="flex-grow: 1; flex-basis: 0;">
|
<ui:VisualElement name="item-details-container" class="container" style="flex-grow: 1; flex-basis: 0;">
|
||||||
<ui:VisualElement name="item-details-header" class="header" />
|
<ui:VisualElement name="item-details-header" class="header" />
|
||||||
<ui:VisualElement name="item-details-content" style="flex-grow: 0;">
|
<ui:VisualElement name="item-details-content" data-source="project://database/Assets/SOAP/Items/SelectedItem.asset?fileID=11400000&guid=37d00232a0bee1e8e923705187ff2187&type=2#SelectedItem" style="flex-grow: 0;">
|
||||||
<ui:VisualElement name="item-details-title-container" style="flex-wrap: nowrap; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px;">
|
<ui:VisualElement name="item-details-title-container" style="flex-wrap: nowrap; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px;">
|
||||||
<ui:Label text="ITEM NAME" name="item-details-title-label" class="title">
|
<ui:Label name="item-details-title-label" class="title">
|
||||||
<Bindings>
|
<Bindings>
|
||||||
<ui:DataBinding property="text" data-source-path="value.value.displayName" binding-mode="ToTarget" />
|
<ui:DataBinding property="text" data-source-path="value.value.displayName" binding-mode="ToTarget" />
|
||||||
</Bindings>
|
</Bindings>
|
||||||
</ui:Label>
|
</ui:Label>
|
||||||
<ui:Label text="Item description body." name="item-details-content-label" style="flex-wrap: nowrap; white-space: pre-wrap; text-overflow: ellipsis;">
|
<ui:Label name="item-details-content-label" style="flex-wrap: nowrap; white-space: pre-wrap; text-overflow: ellipsis;">
|
||||||
<Bindings>
|
<Bindings>
|
||||||
<ui:DataBinding property="text" data-source-path="value.value.description" binding-mode="ToTarget" />
|
<ui:DataBinding property="text" data-source-path="value.value.description" binding-mode="ToTarget" />
|
||||||
</Bindings>
|
</Bindings>
|
||||||
|
|
Loading…
Add table
Reference in a new issue