Game.UI.Widgets.IListAdapter
Assembly: Assembly-CSharp
Namespace: Game.UI.Widgets
Type: interface
Base: None (interface)
Summary:
Interface used by the UI list widget system to provide and manage list elements for a list/collection view. Implementations expose the current number of elements and capabilities (resizable, sortable), respond to UI requests to update a visible range, produce widget instances for rendering, and support element mutation operations (add, insert, duplicate, move, delete, clear). Implement this interface when creating custom adapters for list UI controls in Cities: Skylines 2 mod UI code.
Key implementation notes: - length must always reflect the current number of logical elements. - resizable indicates whether Add/Insert/Delete/Clear operations are supported by the adapter. - sortable indicates whether MoveElement is supported. - UpdateRange(startIndex, endIndex) is called when the UI needs the adapter to prepare or refresh element data for the specified visible range; the method should return true if the UI must update/redraw as a result of changes. - BuildElementsInRange should enumerate/create the IWidget instances corresponding to the currently needed range (commonly used by virtualized lists).
Fields
This interface defines no fields.
Properties
-
public int length { get; }
Expose the current number of elements available through the adapter. The list UI relies on this value to determine scroll extents and valid indices. -
public bool resizable { get; }
Indicates whether the adapter supports modifications that change the element count (AddElement, InsertElement, DeleteElement, Clear). If false, the UI should disable controls that would change the number of elements. -
public bool sortable { get; }
Indicates whether elements can be reordered via MoveElement. If false, the UI should disable drag/reorder operations.
Constructors
- Interfaces do not define constructors. Implementing classes should initialize any internal data structures as needed.
Methods
-
bool UpdateRange(int startIndex, int endIndex)
Called by the list UI to notify the adapter that a given visible range (inclusive, or as defined by the UI) needs to be prepared or refreshed. Implementations should ensure any data necessary for the given indices is ready. Return true if the adapter's data changed in a way that requires the UI to rebuild/redraw its visible elements. -
IEnumerable<IWidget> BuildElementsInRange()
Provide an enumeration of IWidget instances corresponding to the currently required elements (typically the last range passed to UpdateRange or whatever range the UI expects). This method is commonly used by virtualized lists to obtain the concrete widget objects to render. Implementations may create, reuse, or pool widgets as appropriate. -
int AddElement()
Append a new element to the end of the collection and return its index. If the adapter is not resizable, either throw or return a sentinel (implementation-defined) — prefer throwing or otherwise signalling the operation is unsupported so the caller can react. -
void InsertElement(int index)
Insert a new element at the specified index. Validate the index (0..length) and update internal state. If the adapter is not resizable, this operation should be disallowed. -
int DuplicateElement(int index)
Create a copy/duplicate of the element at index, insert the duplicate (commonly right after the original), and return the index of the newly created duplicate. Implementations should decide whether this is a shallow or deep copy based on the element semantics. -
void MoveElement(int fromIndex, int toIndex)
Move/reorder an element from fromIndex to toIndex. If sortable is false, this operation should be disallowed. Implementations must update internal ordering and ensure subsequent length/index values are consistent. -
void DeleteElement(int index)
Remove the element at the given index. If resizable is false, this operation should be disallowed. Implementations should properly dispose or release any resources associated with the removed element (widgets, pooled objects, etc.). -
void Clear()
Remove all elements from the adapter. If resizable is false, this operation should be disallowed. Implementations should clear internal collections and release resources.
Usage Example
// Simple example adapter that backs a list widget with a List<IWidget>.
// This is a minimal illustration — real implementations need to create
// concrete IWidget instances and integrate with the UI lifecycle.
public class SimpleListAdapter : IListAdapter
{
private readonly List<IWidget> _items = new List<IWidget>();
public int length => _items.Count;
public bool resizable => true;
public bool sortable => true;
// Called when the UI asks to prepare a visible range.
public bool UpdateRange(int startIndex, int endIndex)
{
// Ensure indices are valid and prepare any data for widgets.
// Return true if data was changed that requires the UI to refresh.
startIndex = Math.Max(0, startIndex);
endIndex = Math.Min(length - 1, endIndex);
// No data changed in this simple example:
return false;
}
// Provide widgets for the current visible region (could be based on last UpdateRange call).
public IEnumerable<IWidget> BuildElementsInRange()
{
foreach (var widget in _items)
yield return widget;
}
public int AddElement()
{
IWidget newWidget = /* create or obtain widget instance */;
_items.Add(newWidget);
return _items.Count - 1;
}
public void InsertElement(int index)
{
IWidget newWidget = /* create or obtain widget instance */;
_items.Insert(index, newWidget);
}
public int DuplicateElement(int index)
{
var original = _items[index];
IWidget copy = /* clone original or create a new widget with same state */;
_items.Insert(index + 1, copy);
return index + 1;
}
public void MoveElement(int fromIndex, int toIndex)
{
var item = _items[fromIndex];
_items.RemoveAt(fromIndex);
_items.Insert(toIndex, item);
}
public void DeleteElement(int index)
{
_items.RemoveAt(index);
}
public void Clear()
{
_items.Clear();
}
}
Notes: - Follow Unity/CS conventions for creating and reusing widget instances (pooling where appropriate). - Ensure thread-safety if the adapter is accessed from multiple threads (UI updates in Cities: Skylines 2 are generally on the main thread). - When the adapter changes data, notify the owning list control or return true from UpdateRange so the UI can refresh.