Class UITKItemGridPanel
Shared behaviour for a panel that draws a character's item container as a grid of slots.
public abstract class UITKItemGridPanel : UITKCharacterControl
- Inheritance
-
ObjectComponentBehaviourMonoBehaviourUITKItemGridPanel
- Derived
- Inherited Members
-
MonoBehaviour.IsInvoking()MonoBehaviour.CancelInvoke()MonoBehaviour.StopCoroutine(Coroutine)MonoBehaviour.StopAllCoroutines()MonoBehaviour.destroyCancellationTokenMonoBehaviour.useGUILayoutMonoBehaviour.didStartMonoBehaviour.didAwakeMonoBehaviour.runInEditModeBehaviour.enabledBehaviour.isActiveAndEnabledComponent.GetComponent<T>()Component.TryGetComponent<T>(out T)Component.GetComponentInChildren<T>()Component.GetComponentsInChildren<T>()Component.GetComponentInParent<T>()Component.GetComponentsInParent<T>()Component.GetComponents<T>()Component.GetComponentIndex()Component.CompareTag(TagHandle)Component.transformComponent.transformHandleComponent.gameObjectComponent.tagObject.GetEntityId()Object.GetInstanceID()Object.GetHashCode()Object.InstantiateAsync<T>(T)Object.InstantiateAsync<T>(T, Transform)Object.InstantiateAsync<T>(T, Vector3, Quaternion)Object.InstantiateAsync<T>(T, Transform, Vector3, Quaternion)Object.Instantiate(Object, Vector3, Quaternion)Object.Instantiate(Object, Vector3, Quaternion, Transform)Object.Instantiate(Object)Object.Instantiate(Object, Scene)Object.Instantiate<T>(T, InstantiateParameters)Object.Instantiate<T>(T, Vector3, Quaternion, InstantiateParameters)Object.Instantiate(Object, Transform)Object.Instantiate<T>(T)Object.Instantiate<T>(T, Vector3, Quaternion)Object.Instantiate<T>(T, Vector3, Quaternion, Transform)Object.Instantiate<T>(T, Transform)Object.Destroy(Object)Object.DestroyImmediate(Object)Object.DontDestroyOnLoad(Object)Object.DestroyObject(Object)Object.FindObjectsOfType<T>()Object.FindObjectsByType<T>(FindObjectsSortMode)Object.FindObjectsByType<T>(FindObjectsInactive, FindObjectsSortMode)Object.FindObjectOfType<T>()Object.FindFirstObjectByType<T>()Object.FindAnyObjectByType<T>()Object.FindFirstObjectByType<T>(FindObjectsInactive)Object.FindAnyObjectByType<T>(FindObjectsInactive)Object.FindObjectsByType<T>()Object.FindObjectsByType<T>(FindObjectsInactive)Object.ToString()Object.nameObject.hideFlags
Remarks
The bank and the inventory were separate implementations of the same panel — 87% identical after allowing for their vocabulary, sharing twenty-four identically named private methods. That is why a defect fixed in one stayed in the other: the capacity readout counted icons rather than items, was found and corrected in the inventory, and went on being wrong in the bank until it was reported again from play. A second copy does not double the work of a fix, it halves the chance of one.
What made unifying them straightforward is that the domain model had already done it: IBankController and IInventoryController both derive from IItemContainer, which exposes everything this view needs — the slot list, the emptiness test, the item accessor and the two change events. The panels simply were not using it. Nothing here knows which container it is drawing.
The grid is a view of the replicated container and nothing else: no click writes to a slot. A request goes out, the slot is marked as waiting, and the container being replicated back is what changes what the player sees.
Fields
DRAG_OBJECT_NAME
protected const string DRAG_OBJECT_NAME = "UIDragObject"
Field Value
INPUT_DIALOG_NAME
protected const string INPUT_DIALOG_NAME = "UIDialogInputBox"
Field Value
TOOLTIP_NAME
protected const string TOOLTIP_NAME = "UITooltip"
Field Value
slotViews
Slot views indexed by container slot index.
protected readonly List<UITKItemGridPanel.SlotView> slotViews
Field Value
Properties
CapacityFillName
Name of the footer capacity bar fill.
protected virtual string CapacityFillName { get; }
Property Value
CssHidden
USS class hiding an element.
protected string CssHidden { get; }
Property Value
DragType
The drag and operation-tracker identity of this panel's slots.
protected abstract ReferenceButtonType DragType { get; }
Property Value
EmptyName
Name of the label shown when nothing is stored.
protected virtual string EmptyName { get; }
Property Value
FreeName
Name of the footer label counting free slots.
protected virtual string FreeName { get; }
Property Value
OwnContainer
This panel's own container, or null when the character does not have one yet.
protected IItemContainer OwnContainer { get; }
Property Value
OwnInventoryType
This panel's container, as the server names it in a request.
protected abstract InventoryType OwnInventoryType { get; }
Property Value
Prefix
Element and USS name prefix for this panel, without a trailing dash.
protected abstract string Prefix { get; }
Property Value
Remarks
Every panel-specific name is this prefix plus a fixed suffix — "bank-used" and "inv-used", "bank-slot__lock--pending" and "inv-slot__lock--pending". Ten constants followed that pattern in each panel without exception, so one string replaces all twenty. A panel whose markup does not follow it should override the names below rather than bend the prefix.
QuickTransferTarget
The container a shift-click sends an item to, or null when this panel has nowhere to send one.
protected virtual ReferenceButtonType? QuickTransferTarget { get; }
Property Value
UsedName
Name of the footer label counting occupied slots.
protected virtual string UsedName { get; }
Property Value
Methods
ApplyPerOpenContent()
Re-reads the whole grid from the character, rebuilding it only if it is stale.
protected void ApplyPerOpenContent()
BeginDragFromSlot(UITKDragObject, IItemContainer, int)
Starts a drag from an occupied slot.
protected void BeginDragFromSlot(UITKDragObject dragObject, IItemContainer container, int slotIndex)
Parameters
dragObjectUITKDragObjectcontainerIItemContainerslotIndexint
CompleteDropOntoSlot(UITKDragObject, IItemContainer, int)
Drops whatever the drag is carrying onto slotIndex.
protected void CompleteDropOntoSlot(UITKDragObject dragObject, IItemContainer container, int slotIndex)
Parameters
dragObjectUITKDragObjectcontainerIItemContainerslotIndexint
Remarks
This replaced a call to the containers' own CanSwapItemSlots, whose entire body
is return !(fromInventory == InventoryType.Inventory && from == to). It
does not look at the containers at all, so it approved moves out of empty slots, out of
locked slots, and into indices past the end; and because the one case it does check
names InventoryType.Inventory, it never even caught a bank slot dropped on
itself. The server rejects all of it, so nothing was corrupted — what it cost was a
round trip and, before ItemOperationFailedBroadcast, silence.
CompleteUnequipInto(UITKDragObject, int)
Sends an unequip whose destination is this container.
protected void CompleteUnequipInto(UITKDragObject dragObject, int equipmentSlot)
Parameters
dragObjectUITKDragObjectequipmentSlotint
HandleSlotLeftClick(int)
Left-click: completes an in-progress drag or begins dragging this slot's item.
protected virtual void HandleSlotLeftClick(int slotIndex)
Parameters
slotIndexint
HandleSlotRightClick(int)
Right-click on a slot: offers to split the stack in it. Issue #198.
protected virtual void HandleSlotRightClick(int slotIndex)
Parameters
slotIndexintThe slot that was clicked.
Remarks
A panel with a better use for the click (the inventory wears what can be worn) overrides this and falls back to it for everything else, so a stack of arrows splits the same way in the bag and in the bank.
Hide(bool)
Hides the panel and abandons anything it had in flight.
public override void Hide(bool overrideIsAlwaysOpen)
Parameters
overrideIsAlwaysOpenboolWhen true, the call is a no-op.
Remarks
Closing is not a neutral act: walking out of range of the interactable that opened the panel is one of the ways the server refuses an operation, so a slot left marked as waiting after the panel closes has a very good chance of never being answered.
IsSlotBlocked(int)
Reports whether a slot is unavailable for a new request, for any reason.
protected bool IsSlotBlocked(int slotIndex)
Parameters
slotIndexint
Returns
OnAfterShow()
Fills the grid on every show, including the very first one.
protected override void OnAfterShow()
Remarks
THE CONTRACT: enabling the document re-clones the UXML, so anything written before
Show() is discarded. OnAfterStarting covers later opens, but on the first
ever open hasStarted is still false and ReinitializeIfTreeReplaced bails
out before calling it — and a panel opened by a broadcast has its first open triggered
by something the player did rather than at startup. Both hooks do the work, and both
are idempotent.
OnAfterStarting()
Rebuilds the grid after the visual tree has been replaced.
protected override void OnAfterStarting()
OnClientSet()
Joins the shared operation tracker. Derived panels extend this to register broadcasts.
public override void OnClientSet()
OnClientUnset()
Leaves the shared operation tracker. Derived panels extend this to unregister broadcasts.
public override void OnClientUnset()
OnDestroying()
Destroys all runtime slot elements and drops every subscription when the control is destroyed.
public override void OnDestroying()
OnPostSetCharacter()
Builds the grid for the newly set character and subscribes to slot events.
public override void OnPostSetCharacter()
OnPreSetCharacter()
Unsubscribes from slot events before the character is replaced.
public override void OnPreSetCharacter()
OnPreUnsetCharacter()
Drops every subscription and in-flight operation before the character goes away.
public override void OnPreUnsetCharacter()
OnSlotLockChanged(IItemContainer, int, bool)
Called when the lock state of a slot changes.
public void OnSlotLockChanged(IItemContainer container, int slot, bool isLocked)
Parameters
containerIItemContainerslotintisLockedbool
OnSlotUpdated(IItemContainer, Item, int)
Called when a slot's item changes.
public void OnSlotUpdated(IItemContainer container, Item item, int slotIndex)
Parameters
containerIItemContaineritemItemslotIndexint
Remarks
The slot arriving from the server IS the acknowledgement of whatever this panel asked for, so the pending mark is released here rather than on a separate reply message.
OnStarting()
Queries named elements and wires up the close button.
public override void OnStarting()
OnTick()
Times out item operations whose reply never arrived.
protected override void OnTick()
RegisterExtraSlotCallbacks(VisualElement, int)
Lets a panel register additional callbacks on a freshly created slot.
protected virtual void RegisterExtraSlotCallbacks(VisualElement slotRoot, int slotIndex)
Parameters
slotRootVisualElementThe slot element being created.
slotIndexintThe slot's index, already captured for closures.
Remarks
Registered here rather than after the fact because these elements are discarded and rebuilt, so a panel that attached its handlers elsewhere would lose them on the next rebuild.
ReleaseAndClearDrag()
Abandons this panel's in-flight operations and any drag that started here.
protected void ReleaseAndClearDrag()
ResolveContainer(ReferenceButtonType)
Resolves the character's container for a drag source type.
protected IItemContainer ResolveContainer(ReferenceButtonType type)
Parameters
typeReferenceButtonType
Returns
SendQuickTransferRequest(int, int)
Sends the request that moves an item out of this panel and into QuickTransferTarget.
protected virtual void SendQuickTransferRequest(int fromSlot, int toSlot)
Parameters
fromSlotintSlot in this panel the item is leaving.
toSlotintSlot in the target container it is going to.
Remarks
The broadcast belongs to the DESTINATION container, not this one — moving into the bank is a bank swap whoever asked for it — so the panel losing the item is the one that has to name the other panel's request.
SendSplitRequest(int, int, InventoryType, uint)
Asks the server to split part of a stack into one of this panel's slots. Issue #198.
protected abstract void SendSplitRequest(int fromSlot, int toSlot, InventoryType fromInventory, uint amount)
Parameters
fromSlotintSlot holding the stack being split.
toSlotintSlot in this panel the split half is going to.
fromInventoryInventoryTypeContainer holding the stack being split.
amountuintHow much to take off it.
Remarks
As with SendSwapRequest(int, int, InventoryType), the request names its DESTINATION container, so the panel receiving the split half is the one that sends it.
SendSwapRequest(int, int, InventoryType)
Asks the server to move an item into one of this panel's slots.
protected abstract void SendSwapRequest(int fromSlot, int toSlot, InventoryType fromInventory)
Parameters
fromSlotintSlot the item is leaving.
toSlotintSlot in this panel it is going to.
fromInventoryInventoryTypeContainer the item is leaving.
Remarks
The only part of a drop that differs between panels: the request carries the same three fields either way, but the broadcast type names its destination container.
TryPromptSplit(int)
Asks how much of the stack in slotIndex to pick up, then starts a
drag carrying just that much.
protected void TryPromptSplit(int slotIndex)
Parameters
slotIndexintSlot holding the stack to split.
Remarks
Shift-click already means "send to the other container" (issue #197) and press-drag already means "move the whole stack", so the split is asked for another way: a right-click on a stack of two or more opens a quantity prompt, and accepting it picks the split half up as a drag. The drop then names its destination exactly as a drag of the whole stack would, which is what lets the split reuse every check a drop makes.
Nothing is written on this client at any point. The prompt starts a drag, the drop sends a request, and the two slots repaint when the server sends them back — the same contract as every other item operation here.
TryQuickTransfer(int)
Moves an item to the other open container without a drag.
protected void TryQuickTransfer(int slotIndex)
Parameters
slotIndexintSlot holding the item to send.
Remarks
Banking a bagful is the operation players repeat most, and doing it by drag means one press, one aim and one release per item across two panels.
The destination is the first free slot this client can see, and the request is the same swap a drag onto that slot would send. That is deliberate: it carries exactly the risk the drag it replaces already carries, no more. A slot this client believes is empty and the server does not would swap two items rather than move one — but the player aiming a drag at that same slot gets the same outcome, so quick transfer is not introducing a class of mistake, only saving the aiming.