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:
|
||||
Description:
|
||||
value:
|
||||
value: 0
|
||||
value: -50
|
||||
clamp: 1
|
||||
minMax: {x: -50, y: 10}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,8 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using KitsuneCafe.Sys;
|
||||
using ObservableCollections;
|
||||
using UnityEngine;
|
||||
|
@ -92,11 +94,14 @@ namespace KitsuneCafe.ItemSystem
|
|||
[SerializeField]
|
||||
private int capacity = 8;
|
||||
|
||||
public event NotifyCollectionChangedEventHandler<InventoryItem> CollectionChanged;
|
||||
|
||||
public int Capacity => capacity;
|
||||
|
||||
public int Count => items.Count;
|
||||
|
||||
public bool IsEmpty => Count == 0;
|
||||
|
||||
public bool IsFull => Count == Capacity;
|
||||
|
||||
public object SyncRoot => ((IList)items).SyncRoot;
|
||||
|
@ -107,7 +112,11 @@ namespace KitsuneCafe.ItemSystem
|
|||
|
||||
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]
|
||||
{
|
||||
|
@ -115,6 +124,7 @@ namespace KitsuneCafe.ItemSystem
|
|||
set => items[index] = value;
|
||||
}
|
||||
|
||||
|
||||
public IEnumerable<InventoryItem> Find(Func<InventoryItem, bool> predicate)
|
||||
{
|
||||
for (int i = 0; i < Count; i++)
|
||||
|
@ -135,9 +145,12 @@ namespace KitsuneCafe.ItemSystem
|
|||
return Result.Err<int, InventoryError>(InventoryError.InvalidQuantity);
|
||||
}
|
||||
|
||||
List<InventoryItem> existing = new();
|
||||
List<InventoryItem> updated = new();
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
var existingItem = items[i];
|
||||
existing.Add(existingItem);
|
||||
|
||||
if (existingItem.Equals(item))
|
||||
{
|
||||
|
@ -147,6 +160,7 @@ namespace KitsuneCafe.ItemSystem
|
|||
}
|
||||
|
||||
var consumedAmount = existingItem.IncreaseCount(count, out var updatedItem);
|
||||
updated.Add(updatedItem.Value);
|
||||
items[i] = updatedItem.Value;
|
||||
|
||||
count -= consumedAmount;
|
||||
|
@ -157,11 +171,13 @@ namespace KitsuneCafe.ItemSystem
|
|||
}
|
||||
}
|
||||
|
||||
Notify(NotifyCollectionChangedAction.Replace, updated, existing);
|
||||
return Result.Ok<int, InventoryError>(count);
|
||||
}
|
||||
|
||||
private IResult<Unit, InventoryError> AddNew(Item item, int count)
|
||||
{
|
||||
List<InventoryItem> added = new();
|
||||
while (count > 0)
|
||||
{
|
||||
if (IsFull)
|
||||
|
@ -171,9 +187,10 @@ namespace KitsuneCafe.ItemSystem
|
|||
|
||||
count -= InventoryItem.Create(item, count, out var newItem);
|
||||
items.Add(newItem.Value);
|
||||
|
||||
added.Add(newItem.Value);
|
||||
}
|
||||
|
||||
Notify(NotifyCollectionChangedAction.Add, added);
|
||||
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)
|
||||
{
|
||||
if (count <= 0)
|
||||
|
@ -196,6 +239,8 @@ namespace KitsuneCafe.ItemSystem
|
|||
return Result.Err<Unit, InventoryError>(InventoryError.InvalidQuantity);
|
||||
}
|
||||
|
||||
List<InventoryItem> removed = new();
|
||||
List<InventoryItem> updated = new();
|
||||
for (int i = items.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var existingItem = items[i];
|
||||
|
@ -206,15 +251,22 @@ namespace KitsuneCafe.ItemSystem
|
|||
{
|
||||
existingItem.ReduceCount(count, out var updatedItem);
|
||||
items[i] = updatedItem.Value;
|
||||
|
||||
removed.Add(existingItem);
|
||||
updated.Add(updatedItem.Value);
|
||||
|
||||
Notify(NotifyCollectionChangedAction.Remove, updated, removed);
|
||||
return Result.Ok<Unit, InventoryError>(Unit.Default);
|
||||
}
|
||||
else
|
||||
{
|
||||
count -= existingItem.Count;
|
||||
items.RemoveAt(i);
|
||||
removed.Add(existingItem);
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
Notify(NotifyCollectionChangedAction.Remove, updated, removed);
|
||||
return Result.Ok<Unit, InventoryError>(Unit.Default);
|
||||
}
|
||||
}
|
||||
|
@ -226,6 +278,7 @@ namespace KitsuneCafe.ItemSystem
|
|||
return Result.Err<Unit, InventoryError>(InventoryError.NotEnoughQuantity);
|
||||
}
|
||||
|
||||
Notify(NotifyCollectionChangedAction.Remove, updated, removed);
|
||||
return Result.Ok<Unit, InventoryError>(Unit.Default);
|
||||
}
|
||||
|
||||
|
@ -291,5 +344,71 @@ namespace KitsuneCafe.ItemSystem
|
|||
{
|
||||
((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 record RotateEvent(Direction Direction, int FirstIndex);
|
||||
public record RotateEvent(Direction Direction, int FirstIndex, object CurrentItem);
|
||||
|
||||
public enum Direction
|
||||
{
|
||||
|
@ -29,7 +29,6 @@ namespace KitsuneCafe.UI
|
|||
if (displayCount != value)
|
||||
{
|
||||
displayCount = value;
|
||||
CreateIndices();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,15 +42,14 @@ namespace KitsuneCafe.UI
|
|||
if (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;
|
||||
public IReadOnlyList<int> Indices => indices;
|
||||
private int currentIndex = 0;
|
||||
public int SelectedIndex => currentIndex;
|
||||
|
||||
public readonly ICommand<Direction> RotateCommand;
|
||||
|
||||
|
@ -59,52 +57,113 @@ namespace KitsuneCafe.UI
|
|||
|
||||
public RecyclerViewModel()
|
||||
{
|
||||
indices = new();
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (direction == Direction.Clockwise)
|
||||
var dir = direction switch
|
||||
{
|
||||
indices.RemoveAt(0);
|
||||
var next = indices.Last() + 1;
|
||||
next %= ItemSource.Count;
|
||||
indices.Add(next);
|
||||
Notify(direction);
|
||||
}
|
||||
else if (direction == Direction.CounterClockwise)
|
||||
Direction.Clockwise => 1,
|
||||
Direction.CounterClockwise => -1,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
|
||||
|
||||
if (dir != 0)
|
||||
{
|
||||
indices.RemoveAt(ItemSource.Count - 1);
|
||||
var count = ItemSource.Count;
|
||||
var previous = indices[0] - 1;
|
||||
previous += count % count;
|
||||
indices.Insert(0, previous);
|
||||
currentIndex = WrapIndex(currentIndex + dir);
|
||||
Notify(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 int ElementIndex { get; set; }
|
||||
public int DataIndex { get; set; }
|
||||
public int SelectedIndex;
|
||||
public object SelectedItem;
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
base.Init();
|
||||
bubbles = true;
|
||||
tricklesDown = true;
|
||||
}
|
||||
}
|
||||
|
||||
[UxmlElement]
|
||||
|
@ -138,17 +197,17 @@ namespace KitsuneCafe.UI
|
|||
}
|
||||
}
|
||||
|
||||
private IBinder binder;
|
||||
private VisualTreeAsset template;
|
||||
|
||||
[CreateProperty]
|
||||
public IBinder Binder
|
||||
[UxmlAttribute, CreateProperty]
|
||||
public VisualTreeAsset Template
|
||||
{
|
||||
get => binder;
|
||||
get => template;
|
||||
set
|
||||
{
|
||||
if (binder != value)
|
||||
if (template != value)
|
||||
{
|
||||
binder = value;
|
||||
template = value;
|
||||
CreateItems();
|
||||
Rebind();
|
||||
}
|
||||
|
@ -173,18 +232,20 @@ namespace KitsuneCafe.UI
|
|||
private void CreateItems()
|
||||
{
|
||||
Clear();
|
||||
if (DisplayCount == 0 || binder == null) { return; }
|
||||
if (DisplayCount == 0 || template == null) { return; }
|
||||
for (int i = 0; i < DisplayCount; i++)
|
||||
{
|
||||
Add(binder.CreateItem());
|
||||
var ve = template.CloneTree();
|
||||
ve.focusable = true;
|
||||
Add(ve);
|
||||
}
|
||||
|
||||
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++)
|
||||
{
|
||||
|
@ -199,34 +260,35 @@ namespace KitsuneCafe.UI
|
|||
|
||||
private void OnRotated(object sender, RecyclerViewModel.RotateEvent e)
|
||||
{
|
||||
VisualElement recycled;
|
||||
switch (e.Direction)
|
||||
var first = 0;
|
||||
var last = DisplayCount - 1;
|
||||
|
||||
var (from, to) = e.Direction switch
|
||||
{
|
||||
case RecyclerViewModel.Direction.Clockwise:
|
||||
recycled = this[0];
|
||||
RemoveAt(0);
|
||||
Insert(DisplayCount - 1, recycled);
|
||||
TryBindItem(recycled, DisplayCount - 1);
|
||||
NotifySelection();
|
||||
break;
|
||||
case RecyclerViewModel.Direction.CounterClockwise:
|
||||
recycled = this[DisplayCount - 1];
|
||||
RemoveAt(DisplayCount - 1);
|
||||
Insert(0, recycled);
|
||||
TryBindItem(recycled, 0);
|
||||
NotifySelection();
|
||||
break;
|
||||
}
|
||||
RecyclerViewModel.Direction.Clockwise => (first, last),
|
||||
RecyclerViewModel.Direction.CounterClockwise => (last, first),
|
||||
RecyclerViewModel.Direction.None => (-1, -1)
|
||||
};
|
||||
|
||||
if (from == -1 && to == -1) { return; }
|
||||
|
||||
var element = this[from];
|
||||
|
||||
RemoveAt(from);
|
||||
Insert(to, element);
|
||||
|
||||
element.dataSource = viewModel.GetItem(viewModel.GetOffset(to));
|
||||
|
||||
FocusFirst();
|
||||
NotifySelection();
|
||||
}
|
||||
|
||||
private void NotifySelection()
|
||||
{
|
||||
using SelectEvent evt = SelectEvent.GetPooled();
|
||||
evt.target = this[0];
|
||||
evt.ElementIndex = 0;
|
||||
evt.DataIndex = viewModel.Indices[0];
|
||||
evt.SelectedIndex = viewModel.SelectedIndex;
|
||||
evt.SelectedItem = viewModel.GetItem(evt.SelectedIndex);
|
||||
SendEvent(evt);
|
||||
}
|
||||
|
||||
|
@ -242,15 +304,15 @@ namespace KitsuneCafe.UI
|
|||
{
|
||||
if (HasItem(index))
|
||||
{
|
||||
var idx = viewModel.Indices[index];
|
||||
var idx = viewModel.WrapIndex(index);
|
||||
if (0 <= idx && idx < ItemSource.Count)
|
||||
{
|
||||
binder.BindItem(element, idx);
|
||||
element.dataSource = ItemSource[idx];
|
||||
}
|
||||
}
|
||||
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.SOAP;
|
||||
using KitsuneCafe.UI.MVVM;
|
||||
using ObservableCollections;
|
||||
using R3;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
|
@ -11,7 +12,7 @@ namespace KitsuneCafe.UI
|
|||
{
|
||||
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 ItemPreviewName = "item-preview";
|
||||
|
@ -49,7 +50,8 @@ namespace KitsuneCafe.UI
|
|||
|
||||
private VisualElement root => doc.rootVisualElement;
|
||||
|
||||
private VisualElement indicators;
|
||||
private List<VisualElement> indicators;
|
||||
private RecyclerView itemList;
|
||||
private VisualElement itemPreview;
|
||||
|
||||
private void OnValidate()
|
||||
|
@ -92,29 +94,30 @@ namespace KitsuneCafe.UI
|
|||
|
||||
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.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 =>
|
||||
{
|
||||
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-six" class="indicator" />
|
||||
</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 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;">
|
||||
|
@ -57,16 +57,16 @@
|
|||
<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;" />
|
||||
</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-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:Label text="ITEM NAME" name="item-details-title-label" class="title">
|
||||
<ui:Label name="item-details-title-label" class="title">
|
||||
<Bindings>
|
||||
<ui:DataBinding property="text" data-source-path="value.value.displayName" binding-mode="ToTarget" />
|
||||
</Bindings>
|
||||
</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>
|
||||
<ui:DataBinding property="text" data-source-path="value.value.description" binding-mode="ToTarget" />
|
||||
</Bindings>
|
||||
|
|
Loading…
Add table
Reference in a new issue