public void Init(Rect position, SerializedProperty property, GUIContent label) {
			
			if (property == null) return;
			if (this.inited == true) return;
			
			this.window = (property.serializedObject.targetObject as LayoutWindowType);

			this.items = new List<SerializedProperty>();
			this.components = new List<UnityEngine.UI.Windows.Types.Layout.Component>();
			for (int i = 0; i < property.arraySize; ++i) {
				
				var element = property.GetArrayElementAtIndex(i);
				if (this.window.layout.layout == null) continue;
				
				var rootElement = this.window.layout.layout.GetRootByTag(this.window.layout.components[i].tag);
				if (rootElement != null && rootElement.showInComponentsList == true) {
					
					this.components.Add(this.window.layout.components[i]);
					this.items.Add(element);
					
				}
				
			}
			
			this.onItemDraw = (rect, item) => {
				
				var h = 0f;
				return LayoutSettingsEditor.OnItemDraw(this.window, this.items, this.components, true, true, rect, item, out h);
				
			};
			
			System.Func<int, float> getHeight = (index) => {
				
				var h = 56f;
				LayoutSettingsEditor.OnItemDraw(this.window, this.items, this.components, false, true, new Rect(), this.items[index], out h);
				
				return h;
				
			};
			
			this.elements = new ReorderableListControl(ReorderableListFlags.HideAddButton |
			                                           ReorderableListFlags.HideRemoveButtons |
			                                           ReorderableListFlags.DisableAutoScroll |
			                                           ReorderableListFlags.DisableReordering);
			
			this.adapter = new ComponentsListAdaptor<SerializedProperty>(this.items, this.onItemDraw, getHeight);
			
			this.inited = true;
			
		}
		/// <summary>
		/// Draw layout version of list control.
		/// </summary>
		/// <param name="controlID">Unique ID of list control.</param>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <param name="drawEmpty">Delegate for drawing empty list.</param>
		private void Draw(int controlID, IReorderableListAdaptor adaptor, DrawEmpty drawEmpty) {
			FixStyles();
			PrepareState(controlID, adaptor);

			Rect position;

			if (adaptor.Count > 0)
				position = DrawLayoutListField(controlID, adaptor);
			else
				position = DrawLayoutEmptyList(drawEmpty);

			DrawFooterControls(position, controlID, adaptor);
		}
Exemple #3
0
        protected override void AddItemToCollection(TKey item, ref IDictionary <TKey, TValue> collection, IReorderableListAdaptor adaptor)
        {
            try {
                if (!collection.ContainsKey(item))
                {
                    collection.Add(item, default(TValue));
                }
            } catch (Exception) {
                if (ReferenceEquals(item, null))
                {
                    Debug.LogError("Unable to add null keys to dictionaries; please select an instance first.");
                    return;
                }

                throw;
            }
        }
		/// <summary>
		/// Accept reordering.
		/// </summary>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		private void AcceptReorderDrag(IReorderableListAdaptor adaptor) {
			try {
				// Reorder list as needed!
				s_TargetIndex = Mathf.Clamp(s_TargetIndex, 0, adaptor.Count + 1);
				if (s_TargetIndex != s_AnchorIndex && s_TargetIndex != s_AnchorIndex + 1)
					MoveItem(adaptor, s_AnchorIndex, s_TargetIndex);
			}
			finally {
				StopTrackingReorderDrag();
			}
		}
		/// <summary>
		/// Initializes a new instance of <see cref="ItemMovedEventArgs"/>.
		/// </summary>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <param name="buttonPosition">Position of the add menu button.</param>
		public AddMenuClickedEventArgs(IReorderableListAdaptor adaptor, Rect buttonPosition) {
			this.Adaptor = adaptor;
			this.ButtonPosition = buttonPosition;
		}
		/// <summary>
		/// Duplicate specified item and raises the event <see cref="ItemInserted"/>.
		/// </summary>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <param name="itemIndex">Zero-based index of item.</param>
		protected void DuplicateItem(IReorderableListAdaptor adaptor, int itemIndex) {
			adaptor.Duplicate(itemIndex);
			AutoFocusItem(s_ContextControlID, itemIndex + 1);

			GUI.changed = true;
			ReorderableListGUI.IndexOfChangedItem = -1;

			var args = new ItemInsertedEventArgs(adaptor, itemIndex + 1, true);
			OnItemInserted(args);
		}
		/// <summary>
		/// Calculate height of list control in pixels.
		/// </summary>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <returns>
		/// Required list height in pixels.
		/// </returns>
		public float CalculateListHeight(IReorderableListAdaptor adaptor) {
			FixStyles();

			float totalHeight = ContainerStyle.padding.vertical - 1;

			// Take list items into consideration.
			int count = adaptor.Count;
			for (int i = 0; i < count; ++i)
				totalHeight += adaptor.GetItemHeight(i);
			// Add spacing between list items.
			totalHeight += 4 * count;

			// Add height of footer buttons.
			if (HasFooterButtons)
				totalHeight += FooterButtonStyle.fixedHeight;

			return totalHeight;
		}
		/// <summary>
		/// Invoked to generate context menu for list item.
		/// </summary>
		/// <param name="menu">Menu which can be populated.</param>
		/// <param name="itemIndex">Zero-based index of item which was right-clicked.</param>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		protected virtual void AddItemsToMenu(GenericMenu menu, int itemIndex, IReorderableListAdaptor adaptor) {
			if ((Flags & ReorderableListFlags.DisableReordering) == 0) {
				if (itemIndex > 0)
					menu.AddItem(CommandMoveToTop, false, DefaultContextHandler, CommandMoveToTop);
				else
					menu.AddDisabledItem(CommandMoveToTop);

				if (itemIndex + 1 < adaptor.Count)
					menu.AddItem(CommandMoveToBottom, false, DefaultContextHandler, CommandMoveToBottom);
				else
					menu.AddDisabledItem(CommandMoveToBottom);

				if (HasAddButton) {
					menu.AddSeparator("");

					menu.AddItem(CommandInsertAbove, false, DefaultContextHandler, CommandInsertAbove);
					menu.AddItem(CommandInsertBelow, false, DefaultContextHandler, CommandInsertBelow);

					if ((Flags & ReorderableListFlags.DisableDuplicateCommand) == 0)
						menu.AddItem(CommandDuplicate, false, DefaultContextHandler, CommandDuplicate);
				}
			}

			if (HasRemoveButtons) {
				if (menu.GetItemCount() > 0)
					menu.AddSeparator("");

				menu.AddItem(CommandRemove, false, DefaultContextHandler, CommandRemove);
				menu.AddSeparator("");
				menu.AddItem(CommandClearAll, false, DefaultContextHandler, CommandClearAll);
			}
		}
 protected override void AddItemsToMenu(GenericMenu menu, int itemIndex, IReorderableListAdaptor adaptor)
 {
     menu.AddItem(menuItem1, false, DefaultContextHandler, menuItem1);
 }
Exemple #10
0
 /// <summary>
 /// Draw list field control for adapted collection.
 /// </summary>
 /// <param name="position">Position of control.</param>
 /// <param name="adaptor">Reorderable list adaptor.</param>
 /// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param>
 /// <param name="flags">Optional flags to pass into list field.</param>
 private static void DoListFieldAbsolute(Rect position, IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmptyAbsolute drawEmpty, [System.ComponentModel.DefaultValue(0)] ReorderableListFlags flags)
 {
     ReorderableListControl.DrawControlFromState(position, adaptor, drawEmpty, flags);
 }
Exemple #11
0
 /// <summary>
 /// Draw list field control for adapted collection.
 /// </summary>
 /// <param name="adaptor">Reorderable list adaptor.</param>
 /// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param>
 /// <param name="flags">Optional flags to pass into list field.</param>
 private static void DoListField(IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmpty drawEmpty, [System.ComponentModel.DefaultValue(0)] ReorderableListFlags flags)
 {
     ReorderableListControl.DrawControlFromState(adaptor, drawEmpty, flags);
 }
        protected override void AddItemToCollection(TKey item, ref IDictionary <TKey, TValue> collection, IReorderableListAdaptor adaptor0)
        {
            try {
                if (!collection.ContainsKey(item))
                {
                    var adaptor = adaptor0 as CollectionAdaptor <KeyValuePair <TKey, TValue> >;
                    if (adaptor == null && adaptor0 is PageAdaptor)
                    {
                        PageAdaptor pageAdaptor = (PageAdaptor)adaptor0;
                        adaptor = (CollectionAdaptor <KeyValuePair <TKey, TValue> >)pageAdaptor.BackingAdaptor;
                    }

                    adaptor.Add(new KeyValuePair <TKey, TValue>(item, default(TValue)));
                }
            }
            catch (Exception) {
                if (ReferenceEquals(item, null))
                {
                    Debug.LogError("Unable to add null keys to dictionaries; please select an instance first.");
                    return;
                }

                throw;
            }
        }
 protected override void OnPostEdit(ref T[] collection, IReorderableListAdaptor adaptor)
 {
     collection = ((ArrayAdaptor <T>)adaptor).StoredArray;
 }
Exemple #14
0
 public PageAdaptor(IReorderableListAdaptor backingAdaptor, int startIndex, int endIndex)
 {
     BackingAdaptor = backingAdaptor;
     _startIndex    = startIndex;
     _endIndex      = endIndex;
 }
Exemple #15
0
 ///Load entry content into Editor block, does not thing to do with (int) selected.
 void LoadInfoGroup(InfoLogGroup group)
 {
     infoGroupCache    = group;
     _listAdaptor      = new GenericListAdaptor <InfoLogEntry>(infoGroupCache.entries, DrawListEntry, 16f);
     DrawSideBar_Entry = DrawSideBar_Entries_Normal;
 }
		/// <summary>
		/// Draw list control with absolute positioning.
		/// </summary>
		/// <param name="position">Position of list control in GUI.</param>
		/// <param name="controlID">Unique ID of list control.</param>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <param name="drawEmpty">Delegate for drawing empty list.</param>
		private void Draw(Rect position, int controlID, IReorderableListAdaptor adaptor, DrawEmptyAbsolute drawEmpty) {
			FixStyles();
			PrepareState(controlID, adaptor);

			// Allow for footer area.
			if (HasFooterButtons)
				position.height -= FooterButtonStyle.fixedHeight;

			if (adaptor.Count > 0) {
				DrawListContainerAndItems(position, controlID, adaptor);
				CheckForAutoFocusControl(controlID);
			}
			else {
				DrawEmptyListControl(position, drawEmpty);
			}

			DrawFooterControls(position, controlID, adaptor);
		}
		/// <inheritdoc cref="Draw(Rect, IReorderableListAdaptor, DrawEmptyAbsolute)"/>
		public void Draw(Rect position, IReorderableListAdaptor adaptor) {
			int controlID = GUIUtility.GetControlID(FocusType.Passive);
			Draw(position, controlID, adaptor, null);
		}
 //Nothing in here is used ATM, the context menu is disabled
 protected override void AddItemsToMenu(GenericMenu menu, int itemIndex, IReorderableListAdaptor adaptor)
 {
     menu.AddItem(commandCreate, false, defaultContextHandler, commandCreate);
     menu.AddItem(commandImport, false, defaultContextHandler, commandImport);
 }
		/// <summary>
		/// Call to manually perform command.
		/// </summary>
		/// <remarks>
		/// <para>Warning message is logged to console if attempted to execute unknown command.</para>
		/// </remarks>
		/// <param name="commandName">Name of command. This is the text shown in the context menu.</param>
		/// <param name="itemIndex">Zero-based index of item which was right-clicked.</param>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <returns>
		/// A value of <c>true</c> if command was known; otherwise <c>false</c>.
		/// </returns>
		public bool DoCommand(string commandName, int itemIndex, IReorderableListAdaptor adaptor) {
			if (!HandleCommand(s_ContextCommandName, itemIndex, adaptor)) {
				Debug.LogWarning("Unknown context command.");
				return false;
			}
			return true;
		}
Exemple #20
0
 /// <summary>
 /// Initializes a new instance of <see cref="ItemRemovingEventArgs"/>.
 /// </summary>
 /// <param name="adaptor">Reorderable list adaptor.</param>
 /// <param name="itemIndex">Zero-based index of item.</param>
 public ItemRemovingEventArgs(IReorderableListAdaptor adaptor, int itemIndex)
 {
     this.Adaptor   = adaptor;
     this.ItemIndex = itemIndex;
 }
		/// <summary>
		/// Move item from source index to destination index.
		/// </summary>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <param name="sourceIndex">Zero-based index of source item.</param>
		/// <param name="destIndex">Zero-based index of destination index.</param>
		protected void MoveItem(IReorderableListAdaptor adaptor, int sourceIndex, int destIndex) {
			// Raise event before moving item so that the operation can be cancelled.
			var movingEventArgs = new ItemMovingEventArgs(adaptor, sourceIndex, destIndex);
			OnItemMoving(movingEventArgs);
			if (!movingEventArgs.Cancel) {
				adaptor.Move(sourceIndex, destIndex);

				// Item was actually moved!
				int newIndex = destIndex;
				if (newIndex > sourceIndex)
					--newIndex;
				OnItemMoved(new ItemMovedEventArgs(adaptor, sourceIndex, newIndex));

				GUI.changed = true;
			}
			ReorderableListGUI.IndexOfChangedItem = -1;
		}
Exemple #22
0
 /// <summary>
 /// Initializes a new instance of <see cref="ItemMovingEventArgs"/>.
 /// </summary>
 /// <param name="adaptor">Reorderable list adaptor.</param>
 /// <param name="itemIndex">Zero-based index of item.</param>
 /// <param name="destinationItemIndex">Xero-based index of item destination.</param>
 public ItemMovingEventArgs(IReorderableListAdaptor adaptor, int itemIndex, int destinationItemIndex)
 {
     this.Adaptor              = adaptor;
     this.ItemIndex            = itemIndex;
     this.DestinationItemIndex = destinationItemIndex;
 }
		/// <summary>
		/// Remove all items from list.
		/// </summary>
		/// <remarks>
		/// <para>The event <see cref="ItemRemoving"/> is raised for each item prior to
		/// clearing array and allows entire operation to be cancelled.</para>
		/// </remarks>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <returns>
		/// Returns a value of <c>false</c> if operation was cancelled.
		/// </returns>
		protected bool ClearAll(IReorderableListAdaptor adaptor) {
			if (adaptor.Count == 0)
				return true;

			var args = new ItemRemovingEventArgs(adaptor, 0);
			int count = adaptor.Count;
			for (int i = 0; i < count; ++i) {
				args.ItemIndex = i;
				OnItemRemoving(args);
				if (args.Cancel)
					return false;
			}

			adaptor.Clear();

			GUI.changed = true;
			ReorderableListGUI.IndexOfChangedItem = -1;

			return true;
		}
Exemple #24
0
 /// <summary>
 /// Initializes a new instance of <see cref="ItemMovedEventArgs"/>.
 /// </summary>
 /// <param name="adaptor">Reorderable list adaptor.</param>
 /// <param name="buttonPosition">Position of the add menu button.</param>
 public AddMenuClickedEventArgs(IReorderableListAdaptor adaptor, Rect buttonPosition)
 {
     this.Adaptor        = adaptor;
     this.ButtonPosition = buttonPosition;
 }
		/// <summary>
		/// Prepare initial state for list control.
		/// </summary>
		/// <param name="controlID">Unique ID of list control.</param>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		private void PrepareState(int controlID, IReorderableListAdaptor adaptor) {
			_controlID = controlID;
			_visibleRect = GUIHelper.VisibleRect();

			if ((Flags & ReorderableListFlags.ShowIndices) != 0) {
				int digitCount = Mathf.Max(2, Mathf.CeilToInt(Mathf.Log10((float)adaptor.Count)));
				_indexLabelWidth = digitCount * 8 + 8;
			}
			else {
				_indexLabelWidth = 0;
			}

			_tracking = IsTrackingControl(controlID);

			_allowReordering = (Flags & ReorderableListFlags.DisableReordering) == 0;
		}
Exemple #26
0
 /// <summary>
 /// Initializes a new instance of <see cref="ItemMovedEventArgs"/>.
 /// </summary>
 /// <param name="adaptor">Reorderable list adaptor.</param>
 /// <param name="oldItemIndex">Old zero-based index of item.</param>
 /// <param name="newItemIndex">New zero-based index of item.</param>
 public ItemMovedEventArgs(IReorderableListAdaptor adaptor, int oldItemIndex, int newItemIndex)
 {
     this.Adaptor      = adaptor;
     this.OldItemIndex = oldItemIndex;
     this.NewItemIndex = newItemIndex;
 }
		private void DrawFloatingListItem(EventType eventType, IReorderableListAdaptor adaptor, float targetSlotPosition) {
			if (eventType == EventType.Repaint) {
				Color restoreColor = GUI.color;

				// Fill background of target area.
				Rect targetPosition = s_DragItemPosition;
				targetPosition.y = targetSlotPosition - 1;
				targetPosition.height = 1;

				GUIHelper.DrawTexture(targetPosition, ReorderableListResources.texItemSplitter);

				--targetPosition.x;
				++targetPosition.y;
				targetPosition.width += 2;
				targetPosition.height = s_DragItemPosition.height - 1;

				GUI.color = TargetBackgroundColor;
				GUIHelper.DrawTexture(targetPosition, EditorGUIUtility.whiteTexture);
				
				// Fill background of item which is being dragged.
				--s_DragItemPosition.x;
				s_DragItemPosition.width += 2;
				--s_DragItemPosition.height;

				GUI.color = AnchorBackgroundColor;
				GUIHelper.DrawTexture(s_DragItemPosition, EditorGUIUtility.whiteTexture);

				++s_DragItemPosition.x;
				s_DragItemPosition.width -= 2;
				++s_DragItemPosition.height;

				// Draw horizontal splitter above and below.
				GUI.color = new Color(0f, 0f, 0f, 0.6f);
				targetPosition.y = s_DragItemPosition.y - 1;
				targetPosition.height = 1;
				GUIHelper.DrawTexture(targetPosition, EditorGUIUtility.whiteTexture);

				targetPosition.y += s_DragItemPosition.height;
				GUIHelper.DrawTexture(targetPosition, EditorGUIUtility.whiteTexture);

				GUI.color = restoreColor;
			}

			DrawListItem(eventType, s_DragItemPosition, adaptor, s_AnchorIndex);
		}
Exemple #28
0
 /// <summary>
 /// Initializes a new instance of <see cref="ItemInsertedEventArgs"/>.
 /// </summary>
 /// <param name="adaptor">Reorderable list adaptor.</param>
 /// <param name="itemIndex">Zero-based index of item.</param>
 /// <param name="wasDuplicated">Indicates if inserted item was duplicated from another item.</param>
 public ItemInsertedEventArgs(IReorderableListAdaptor adaptor, int itemIndex, bool wasDuplicated)
 {
     this.Adaptor       = adaptor;
     this.ItemIndex     = itemIndex;
     this.WasDuplicated = wasDuplicated;
 }
		/// <summary>
		/// Do layout version of list field.
		/// </summary>
		/// <param name="controlID">Unique ID of list control.</param>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <returns>
		/// Position of list container area in GUI (excludes footer area).
		/// </returns>
		private Rect DrawLayoutListField(int controlID, IReorderableListAdaptor adaptor) {
			float totalHeight;

			// Calculate position of list field using layout engine.
			if (Event.current.type == EventType.Layout) {
				totalHeight = CalculateListHeight(adaptor);
				s_ContainerHeightCache[controlID] = totalHeight;
			}
			else {
				totalHeight = s_ContainerHeightCache.ContainsKey(controlID)
					? s_ContainerHeightCache[controlID]
					: 0;
			}

			Rect position = GUILayoutUtility.GetRect(GUIContent.none, ContainerStyle, GUILayout.Height(totalHeight));

			// Make room for footer buttons?
			if (HasFooterButtons)
				position.height -= FooterButtonStyle.fixedHeight;

			// Draw list as normal.
			DrawListContainerAndItems(position, controlID, adaptor);

			CheckForAutoFocusControl(controlID);

			return position;
		}
 /// <summary>
 /// Draw list field control for adapted collection.
 /// </summary>
 /// <param name="position">Position of control.</param>
 /// <param name="adaptor">Reorderable list adaptor.</param>
 /// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param>
 /// <param name="flags">Optional flags to pass into list field.</param>
 private static void DoListFieldAbsolute(Rect position, IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmptyAbsolute drawEmpty, ReorderableListFlags flags)
 {
     ReorderableListControl.DrawControlFromState(position, adaptor, drawEmpty, flags);
 }
		/// <inheritdoc cref="Draw(int, IReorderableListAdaptor, DrawEmpty)"/>
		public void Draw(IReorderableListAdaptor adaptor, DrawEmpty drawEmpty) {
			int controlID = GUIUtility.GetControlID(FocusType.Passive);
			Draw(controlID, adaptor, drawEmpty);
		}
 /// <inheritdoc cref="DoListField(IReorderableListAdaptor, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/>
 public static void ListField(IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmpty drawEmpty)
 {
     DoListField(adaptor, drawEmpty, 0);
 }
		/// <summary>
		/// Draw list control with absolute positioning.
		/// </summary>
		/// <param name="position">Position of list control in GUI.</param>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <param name="drawEmpty">Delegate for drawing empty list.</param>
		public void Draw(Rect position, IReorderableListAdaptor adaptor, DrawEmptyAbsolute drawEmpty) {
			int controlID = GUIUtility.GetControlID(FocusType.Passive);
			Draw(position, controlID, adaptor, drawEmpty);
		}
 /// <inheritdoc cref="DoListFieldAbsolute(Rect, IReorderableListAdaptor, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/>
 public static void ListFieldAbsolute(Rect position, IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmptyAbsolute drawEmpty)
 {
     DoListFieldAbsolute(position, adaptor, drawEmpty, 0);
 }
		private void ShowContextMenu(int controlID, int itemIndex, IReorderableListAdaptor adaptor) {
			GenericMenu menu = new GenericMenu();

			s_ContextControlID = controlID;
			s_ContextItemIndex = itemIndex;

			AddItemsToMenu(menu, itemIndex, adaptor);

			if (menu.GetItemCount() > 0)
				menu.ShowAsContext();
		}
 /// <inheritdoc cref="DoListField(IReorderableListAdaptor, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/>
 public static void ListField(IReorderableListAdaptor adaptor, ReorderableListFlags flags)
 {
     DoListField(adaptor, null, flags);
 }
		/// <summary>
		/// Invoked to handle context command.
		/// </summary>
		/// <remarks>
		/// <para>It is important to set the value of <c>GUI.changed</c> to <c>true</c> if any
		/// changes are made by command handler.</para>
		/// <para>Default command handling functionality can be inherited:</para>
		/// <code language="csharp"><![CDATA[
		/// protected override bool HandleCommand(string commandName, int itemIndex, IReorderableListAdaptor adaptor) {
		///     if (base.HandleCommand(itemIndex, adaptor))
		///         return true;
		///     
		///     // Place custom command handling code here...
		///     switch (commandName) {
		///         case "Your Command":
		///             return true;
		///     }
		/// 
		///     return false;
		/// }
		/// ]]></code>
		/// <code language="unityscript"><![CDATA[
		/// function HandleCommand(commandName:String, itemIndex:int, adaptor:IReorderableListAdaptor):boolean {
		///     if (base.HandleCommand(itemIndex, adaptor))
		///         return true;
		///     
		///     // Place custom command handling code here...
		///     switch (commandName) {
		///         case 'Your Command':
		///             return true;
		///     }
		/// 
		///     return false;
		/// }
		/// ]]></code>
		/// </remarks>
		/// <param name="commandName">Name of command. This is the text shown in the context menu.</param>
		/// <param name="itemIndex">Zero-based index of item which was right-clicked.</param>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <returns>
		/// A value of <c>true</c> if command was known; otherwise <c>false</c>.
		/// </returns>
		protected virtual bool HandleCommand(string commandName, int itemIndex, IReorderableListAdaptor adaptor) {
			switch (commandName) {
				case "Move to Top":
					MoveItem(adaptor, itemIndex, 0);
					return true;
				case "Move to Bottom":
					MoveItem(adaptor, itemIndex, adaptor.Count);
					return true;

				case "Insert Above":
					InsertItem(adaptor, itemIndex);
					return true;
				case "Insert Below":
					InsertItem(adaptor, itemIndex + 1);
					return true;
				case "Duplicate":
					DuplicateItem(adaptor, itemIndex);
					return true;

				case "Remove":
					RemoveItem(adaptor, itemIndex);
					return true;
				case "Clear All":
					ClearAll(adaptor);
					return true;

				default:
					return false;
			}
		}
 /// <inheritdoc cref="DoListField(IReorderableListAdaptor, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/>
 public static void ListField(IReorderableListAdaptor adaptor)
 {
     DoListField(adaptor, null, 0);
 }
		/// <summary>
		/// Call to manually perform command.
		/// </summary>
		/// <remarks>
		/// <para>Warning message is logged to console if attempted to execute unknown command.</para>
		/// </remarks>
		/// <param name="command">Content representing command.</param>
		/// <param name="itemIndex">Zero-based index of item which was right-clicked.</param>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <returns>
		/// A value of <c>true</c> if command was known; otherwise <c>false</c>.
		/// </returns>
		public bool DoCommand(GUIContent command, int itemIndex, IReorderableListAdaptor adaptor) {
			return DoCommand(command.text, itemIndex, adaptor);
		}
 /// <inheritdoc cref="DoListFieldAbsolute(Rect, IReorderableListAdaptor, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/>
 public static void ListFieldAbsolute(Rect position, IReorderableListAdaptor adaptor)
 {
     DoListFieldAbsolute(position, adaptor, null, 0);
 }
		/// <summary>
		/// Initializes a new instance of <see cref="ItemMovingEventArgs"/>.
		/// </summary>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <param name="itemIndex">Zero-based index of item.</param>
		/// <param name="destinationItemIndex">Xero-based index of item destination.</param>
		public ItemMovingEventArgs(IReorderableListAdaptor adaptor, int itemIndex, int destinationItemIndex) {
			this.Adaptor = adaptor;
			this.ItemIndex = itemIndex;
			this.DestinationItemIndex = destinationItemIndex;
		}
 /// <inheritdoc cref="CalculateListFieldHeight(IReorderableListAdaptor, ReorderableListFlags)"/>
 public static float CalculateListFieldHeight(IReorderableListAdaptor adaptor)
 {
     return(CalculateListFieldHeight(adaptor, 0));
 }
		/// <summary>
		/// Add item at end of list and raises the event <see cref="ItemInserted"/>.
		/// </summary>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		protected void AddItem(IReorderableListAdaptor adaptor) {
			adaptor.Add();
			AutoFocusItem(s_ContextControlID, adaptor.Count - 1);

			GUI.changed = true;
			ReorderableListGUI.IndexOfChangedItem = -1;

			var args = new ItemInsertedEventArgs(adaptor, adaptor.Count - 1, false);
			OnItemInserted(args);
		}
        public void DoEdit(Rect initialRegion, Rect region, GUIContent label, ref TCollection collection, fiGraphMetadata metadata,
                           IReorderableListAdaptor adaptor)
        {
            Rect bodyRect = new Rect(region);

            bodyRect.height -= GetAddRegionHeightWithMargin(metadata);

            Rect addItemButtonRect, addItemItemRect;

            {
                Rect baseAddItemRect = new Rect(region);
                baseAddItemRect.y     += bodyRect.height + AddRegionMargin;
                baseAddItemRect.height = GetAddRegionHeight(metadata);

                fiRectUtility.SplitLeftHorizontalExact(baseAddItemRect,
                                                       /*leftWidth:*/ ReorderableListGUI.defaultAddButtonStyle.fixedWidth,
                                                       /*margin:*/ 1, out addItemButtonRect, out addItemItemRect);

                // move the margin up
                addItemItemRect.x     += AddRegionBorder;
                addItemItemRect.width -= AddRegionBorder * 2;
                addItemButtonRect.y   -= AddRegionBorder * 2;
                addItemItemRect.y     -= AddRegionBorder;

                if (DisplayAddItemPreview && Event.current.type == EventType.repaint)
                {
                    Rect container = addItemItemRect;
                    container.x      -= AddRegionBorder;
                    container.y      -= AddRegionBorder;
                    container.width  += AddRegionBorder * 2;
                    container.height += AddRegionBorder * 2;
                    ReorderableListGUI.defaultContainerStyle.Draw(container, false, false, false, false);
                }

                addItemButtonRect.height = ReorderableListGUI.defaultAddButtonStyle.fixedHeight;
            }

            // draw the collection elements
            ReorderableListGUI.ListFieldAbsolute(bodyRect, adaptor, DrawEmpty, _listFlags);

            // draw the next key
            metadata.Enter("NextValue").Metadata.GetPersistentMetadata <fiDropdownMetadata>().ForceDisable();

            if (DisplayAddItemPreview)
            {
                var addButtonStyle = ReorderableListGUI.defaultAddButtonStyleFlipped;
                if (adaptor.Count == 0)
                {
                    addButtonStyle = ReorderableListGUI.defaultAddButtonStyleIndependent;
                }

                if (GUI.Button(addItemButtonRect, "", addButtonStyle))
                {
                    AddItemToCollection(_addItem, ref collection, adaptor);
                    GUI.FocusControl(null);
                    _addItem = default(TAddItem);
                }

                EnsureValidAddItem(ref _addItem);
                fiEditorGUI.PushHierarchyMode(false);
                _addItem = _addItemEditor.FirstEditor.Edit(addItemItemRect, GUIContent.none, _addItem,
                                                           metadata.Enter("NextValue"));
                fiEditorGUI.PopHierarchyMode();
            }

            AcceptDragAndDrop(initialRegion, ref collection, adaptor);
        }
		/// <summary>
		/// Remove specified item.
		/// </summary>
		/// <remarks>
		/// <para>The event <see cref="ItemRemoving"/> is raised prior to removing item
		/// and allows removal to be cancelled.</para>
		/// </remarks>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <param name="itemIndex">Zero-based index of item.</param>
		/// <returns>
		/// Returns a value of <c>false</c> if operation was cancelled.
		/// </returns>
		protected bool RemoveItem(IReorderableListAdaptor adaptor, int itemIndex) {
			var args = new ItemRemovingEventArgs(adaptor, itemIndex);
			OnItemRemoving(args);
			if (args.Cancel)
				return false;

			adaptor.Remove(itemIndex);

			GUI.changed = true;
			ReorderableListGUI.IndexOfChangedItem = -1;

			return true;
		}
 /// <summary>
 /// Called after an edit cycle is done if the collection needs to be updated from the adaptor.
 /// </summary>
 protected virtual void OnPostEdit(ref TCollection collection, IReorderableListAdaptor adaptor)
 {
 }
		/// <summary>
		/// Initializes a new instance of <see cref="ItemMovedEventArgs"/>.
		/// </summary>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <param name="oldItemIndex">Old zero-based index of item.</param>
		/// <param name="newItemIndex">New zero-based index of item.</param>
		public ItemMovedEventArgs(IReorderableListAdaptor adaptor, int oldItemIndex, int newItemIndex) {
			this.Adaptor = adaptor;
			this.OldItemIndex = oldItemIndex;
			this.NewItemIndex = newItemIndex;
		}
        /// <summary>
        /// An item has been added to the collection.
        /// </summary>
        protected virtual void AddItemToCollection(TAddItem item, ref TCollection collection, IReorderableListAdaptor adaptor)
        {
            if (typeof(TItem).IsAssignableFrom(typeof(TAddItem)) == false)
            {
                Debug.LogError("Please override AddItemToCollection; " + typeof(TAddItem).CSharpName() +
                               " cannot be converted to " + typeof(TItem).CSharpName());
                return;
            }

            if (collection.GetType().IsArray)
            {
                // TODO: This is a hack. We should remove it. We update the array reference in OnPostEdit, so we have to
                //       add the item to the actual array we will later update.
                var a = (ArrayAdaptor <TItem>)adaptor;
                adaptor.Add();
                a.StoredArray[a.Count - 1] = (TItem)(object)item;
            }
            else
            {
                collection.Add((TItem)(object)item);
            }
        }
		/// <summary>
		/// Generate and draw control from state object.
		/// </summary>
		/// <param name="position">Position of control.</param>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <param name="drawEmpty">Delegate for drawing empty list.</param>
		/// <param name="flags">Optional flags to pass into list field.</param>
		public static void DrawControlFromState(Rect position, IReorderableListAdaptor adaptor, DrawEmptyAbsolute drawEmpty, ReorderableListFlags flags) {
			int controlID = GUIUtility.GetControlID(FocusType.Passive);

			var control = GUIUtility.GetStateObject(typeof(ReorderableListControl), controlID) as ReorderableListControl;
			control.Flags = flags;
			control.Draw(position, controlID, adaptor, drawEmpty);
		}
Exemple #50
0
 /// <summary>
 /// Draw list field control for adapted collection.
 /// </summary>
 /// <param name="adaptor">Reorderable list adaptor.</param>
 /// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param>
 /// <param name="flags">Optional flags to pass into list field.</param>
 private static void DoListField(IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmpty drawEmpty, ReorderableListFlags flags = 0)
 {
     ReorderableListControl.DrawControlFromState(adaptor, drawEmpty, flags);
 }
		/// <summary>
		/// Initializes a new instance of <see cref="ItemInsertedEventArgs"/>.
		/// </summary>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <param name="itemIndex">Zero-based index of item.</param>
		/// <param name="wasDuplicated">Indicates if inserted item was duplicated from another item.</param>
		public ItemInsertedEventArgs(IReorderableListAdaptor adaptor, int itemIndex, bool wasDuplicated) {
			this.Adaptor = adaptor;
			this.ItemIndex = itemIndex;
			this.WasDuplicated = wasDuplicated;
		}
		/// <summary>
		/// Initializes a new instance of <see cref="ItemRemovingEventArgs"/>.
		/// </summary>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		/// <param name="itemIndex">Zero-based index of item.</param>
		public ItemRemovingEventArgs(IReorderableListAdaptor adaptor, int itemIndex) {
			this.Adaptor = adaptor;
			this.ItemIndex = itemIndex;
		}
		private void DrawListItem(EventType eventType, Rect position, IReorderableListAdaptor adaptor, int itemIndex) {
			bool visible = (position.y < _visibleRect.yMax && position.yMax > _visibleRect.y);
			bool draggable = _allowReordering && adaptor.CanDrag(itemIndex);

			Rect itemContentPosition = position;
			itemContentPosition.x = position.x + 2;
			itemContentPosition.y += 1;
			itemContentPosition.width = position.width - 4;
			itemContentPosition.height = position.height - 4;

			// Make space for grab handle?
			if (draggable) {
				itemContentPosition.x += 20;
				itemContentPosition.width -= 20;
			}

			// Make space for element index.
			if (_indexLabelWidth != 0) {
				itemContentPosition.width -= _indexLabelWidth;

				if (eventType == EventType.Repaint && visible)
					s_RightAlignedLabelStyle.Draw(new Rect(itemContentPosition.x, position.y, _indexLabelWidth, position.height - 4), itemIndex + ":", false, false, false, false);

				itemContentPosition.x += _indexLabelWidth;
			}

			// Make space for remove button?
			if (HasRemoveButtons)
				itemContentPosition.width -= 27;

			try {
				s_CurrentItemIndex.Push(itemIndex);
				EditorGUI.BeginChangeCheck();

				if (eventType == EventType.Repaint && visible) {
					// Draw background of list item.
					var backgroundPosition = new Rect(position.x, position.y, position.width, position.height - 1);
					adaptor.DrawItemBackground(backgroundPosition, itemIndex);

					// Draw grab handle?
					if (draggable) {
						var texturePosition = new Rect(position.x + 6, position.y + position.height / 2f - 3, 9, 5);
						GUIHelper.DrawTexture(texturePosition, ReorderableListResources.GetTexture(ReorderableListTexture.GrabHandle));
					}

					// Draw splitter between list items.
					if (itemIndex != 0 && (!_tracking || itemIndex != s_AnchorIndex)) {
						var texturePosition = new Rect(position.x, position.y - 1, position.width, 1);
						GUIHelper.DrawTexture(texturePosition, ReorderableListResources.texItemSplitter);
					}
				}

				// Allow control to be automatically focused.
				if (s_AutoFocusIndex == itemIndex)
					GUI.SetNextControlName("AutoFocus_" + _controlID + "_" + itemIndex);

				// Present actual control.
				adaptor.DrawItem(itemContentPosition, itemIndex);

				if (EditorGUI.EndChangeCheck())
					ReorderableListGUI.IndexOfChangedItem = itemIndex;

				// Draw remove button?
				if (HasRemoveButtons && adaptor.CanRemove(itemIndex)) {
					s_RemoveButtonPosition = position;
					s_RemoveButtonPosition.width = 27;
					s_RemoveButtonPosition.x = itemContentPosition.xMax + 2;
					s_RemoveButtonPosition.height -= 2;

					if (DoRemoveButton(s_RemoveButtonPosition, visible))
						RemoveItem(adaptor, itemIndex);
				}

				// Check for context click?
				if (eventType == EventType.ContextClick && position.Contains(Event.current.mousePosition) && (Flags & ReorderableListFlags.DisableContextMenu) == 0) {
					ShowContextMenu(_controlID, itemIndex, adaptor);
					Event.current.Use();
				}
			}
			finally {
				s_CurrentItemIndex.Pop();
			}
		}
		/// <summary>
		/// Draw additional controls below list control and highlight drop target.
		/// </summary>
		/// <param name="position">Position of list control in GUI.</param>
		/// <param name="controlID">Unique ID of list control.</param>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		private void DrawFooterControls(Rect position, int controlID, IReorderableListAdaptor adaptor) {
			if (HasFooterButtons) {
				Rect buttonPosition = new Rect(position.xMax - 30, position.yMax - 1, 30, FooterButtonStyle.fixedHeight);

				Rect menuButtonPosition = buttonPosition;
				var menuIconNormal = ReorderableListResources.GetTexture(ReorderableListTexture.Icon_AddMenu_Normal);
				var menuIconActive = ReorderableListResources.GetTexture(ReorderableListTexture.Icon_AddMenu_Active);

				if (HasAddButton) {
					// Draw add menu drop-down button.
					if (HasAddMenuButton) {
						menuButtonPosition.x = buttonPosition.xMax - 14;
						menuButtonPosition.xMax = buttonPosition.xMax;
						menuIconNormal = ReorderableListResources.GetTexture(ReorderableListTexture.Icon_Menu_Normal);
						menuIconActive = ReorderableListResources.GetTexture(ReorderableListTexture.Icon_Menu_Active);
						buttonPosition.width -= 5;
						buttonPosition.x = menuButtonPosition.x - buttonPosition.width + 1;
					}

					// Draw add item button.
					var iconNormal = ReorderableListResources.GetTexture(ReorderableListTexture.Icon_Add_Normal);
					var iconActive = ReorderableListResources.GetTexture(ReorderableListTexture.Icon_Add_Active);

					if (GUIHelper.IconButton(buttonPosition, true, iconNormal, iconActive, FooterButtonStyle)) {
						// Append item to list.
						GUIUtility.keyboardControl = 0;
						AddItem(adaptor);
					}
				}
				
				if (HasAddMenuButton) {
					// Draw add menu drop-down button.
					if (GUIHelper.IconButton(menuButtonPosition, true, menuIconNormal, menuIconActive, FooterButtonStyle)) {
						GUIUtility.keyboardControl = 0;
						Rect totalAddButtonPosition = buttonPosition;
						totalAddButtonPosition.xMax = position.xMax;
						OnAddMenuClicked(new AddMenuClickedEventArgs(adaptor, totalAddButtonPosition));

						// This will be helpful in many circumstances; including by default!
						GUIUtility.ExitGUI();
					}
				}
			}
		}
		/// <summary>
		/// Draw list container and items.
		/// </summary>
		/// <param name="position">Position of list control in GUI.</param>
		/// <param name="controlID">Unique ID of list control.</param>
		/// <param name="adaptor">Reorderable list adaptor.</param>
		private void DrawListContainerAndItems(Rect position, int controlID, IReorderableListAdaptor adaptor) {
			// Get local copy of event information for efficiency.
			EventType eventType = Event.current.GetTypeForControl(controlID);
			Vector2 mousePosition = Event.current.mousePosition;
            //if (Event.current.isMouse)
            //    s_MousePosition = GUIUtility.GUIToScreenPoint(mousePosition);

			int newTargetIndex = s_TargetIndex;
			
			// Position of first item in list.
			float firstItemY = position.y + ContainerStyle.padding.top;

			switch (eventType) {
				case EventType.MouseDown:
					if (_tracking) {
						// Cancel drag when other mouse button is pressed.
						s_TrackingCancelBlockContext = true;
						Event.current.Use();
					}
					break;

				case EventType.MouseDrag:
					if (_tracking) {
						// Reset target index and adjust when looping through list items.
						if (mousePosition.y < firstItemY)
							newTargetIndex = 0;
						else if (mousePosition.y >= position.yMax)
							newTargetIndex = adaptor.Count;

						s_DragItemPosition.y = Mathf.Clamp(mousePosition.y + s_AnchorMouseOffset, firstItemY, position.yMax - s_DragItemPosition.height - 1);
					}
					break;

				case EventType.MouseUp:
					if (controlID == GUIUtility.hotControl) {
						// Allow user code to change control over reordering during drag.
						if (!s_TrackingCancelBlockContext && _allowReordering)
							AcceptReorderDrag(adaptor);
						else
							StopTrackingReorderDrag();
						Event.current.Use();
					}
					break;

				case EventType.KeyDown:
					if (_tracking && Event.current.keyCode == KeyCode.Escape) {
						StopTrackingReorderDrag();
						Event.current.Use();
					}
					break;

				case EventType.ExecuteCommand:
					if (s_ContextControlID == controlID) {
						int itemIndex = s_ContextItemIndex;
						try {
							DoCommand(s_ContextCommandName, itemIndex, adaptor);
							Event.current.Use();
						}
						finally {
							s_ContextControlID = 0;
							s_ContextItemIndex = 0;
						}
					}
					break;

				case EventType.Repaint:
					// Draw caption area of list.
					ContainerStyle.Draw(position, GUIContent.none, false, false, false, false);
					break;
			}

			ReorderableListGUI.IndexOfChangedItem = -1;

			// Draw list items!
			Rect itemPosition = new Rect(position.x + 2, firstItemY, position.width - 4, 0);
			float targetSlotPosition = position.yMax - s_DragItemPosition.height - 1;

			float lastMidPoint = 0f;
			float lastHeight = 0f;

			int count = adaptor.Count;
			for (int i = 0; i < count; ++i) {
				itemPosition.y = itemPosition.yMax;
				itemPosition.height = 0;

				if (_tracking) {
					// Does this represent the target index?
					if (i == s_TargetIndex) {
						targetSlotPosition = itemPosition.y;
						itemPosition.y += s_DragItemPosition.height;
					}

					// Do not draw item if it is currently being dragged.
					// Draw later so that it is shown in front of other controls.
					if (i == s_AnchorIndex)
						continue;

					lastMidPoint = itemPosition.y - lastHeight / 2f;
				}

				// Update position for current item.
				itemPosition.height = adaptor.GetItemHeight(i) + 4;
				lastHeight = itemPosition.height;

				if (_tracking && eventType == EventType.MouseDrag) {
					float midpoint = itemPosition.y + itemPosition.height / 2f;

					if (s_TargetIndex < i) {
						if (s_DragItemPosition.yMax > lastMidPoint && s_DragItemPosition.yMax < midpoint)
							newTargetIndex = i;
					}
					else if (s_TargetIndex > i) {
						if (s_DragItemPosition.y > lastMidPoint && s_DragItemPosition.y < midpoint)
							newTargetIndex = i;
					}

					/*if (s_DragItemPosition.y > itemPosition.y && s_DragItemPosition.y <= midpoint)
						newTargetIndex = i;
					else if (s_DragItemPosition.yMax > midpoint && s_DragItemPosition.yMax <= itemPosition.yMax)
						newTargetIndex = i + 1;*/
				}

				// The following may break use of tab key to navigate through controls :/
				if ((Flags & ReorderableListFlags.DisableClipping) == 0) {
					// Clip list item? Performance boost!
					if (itemPosition.yMax < _visibleRect.y - itemPosition.height) {
						// Let's try and trick Unity into maintaining tab key support...
						GUIUtility.GetControlID(FocusType.Keyboard, itemPosition);
						continue;
					}
					if (itemPosition.y > _visibleRect.yMax + itemPosition.height)
						break;
				}

				// Draw list item.
				DrawListItem(eventType, itemPosition, adaptor, i);

				// Did list count change (i.e. item removed)?
				if (adaptor.Count < count) {
					// We assume that it was this item which was removed, so --i allows us
					// to process the next item as usual.
					count = adaptor.Count;
					--i;
					continue;
				}
				
				// Event has already been used, skip to next item.
				if (Event.current.type != EventType.Used) {
					switch (eventType) {
						case EventType.MouseDown:
							if (GUI.enabled && itemPosition.Contains(mousePosition)) {
								// Remove input focus from control before attempting a context click or drag.
								GUIUtility.keyboardControl = 0;

								if (_allowReordering && adaptor.CanDrag(i) && Event.current.button == 0) {
									s_DragItemPosition = itemPosition;

									BeginTrackingReorderDrag(controlID, i);
									s_AnchorMouseOffset = itemPosition.y - mousePosition.y;
									s_TargetIndex = i;

									Event.current.Use();
								}
							}
							break;
/* DEBUG
						case EventType.Repaint:
							GUI.color = Color.red;
							GUI.DrawTexture(new Rect(0, lastMidPoint, 10, 1), EditorGUIUtility.whiteTexture);
							GUI.color = Color.yellow;
							GUI.DrawTexture(new Rect(5, itemPosition.y + itemPosition.height / 2f, 10, 1), EditorGUIUtility.whiteTexture);
							GUI.color = Color.white;
							break;
//*/
					}
				}
			}

			// Item which is being dragged should be shown on top of other controls!
			if (IsTrackingControl(controlID)) {
				lastMidPoint = position.yMax - lastHeight / 2f;

				if (eventType == EventType.MouseDrag) {
					if (s_DragItemPosition.yMax >= lastMidPoint)
						newTargetIndex = count;

					// Force repaint to occur so that dragging rectangle is visible.
					s_TargetIndex = newTargetIndex;
					Event.current.Use();
				}

				DrawFloatingListItem(eventType, adaptor, targetSlotPosition);
/* DEBUG
				if (eventType == EventType.Repaint) {
					GUI.color = Color.blue;
					GUI.DrawTexture(new Rect(100, lastMidPoint, 20, 1), EditorGUIUtility.whiteTexture);
					GUI.color = Color.white;
				}
//*/
			}
			
			// Fake control to catch input focus if auto focus was not possible.
			GUIUtility.GetControlID(FocusType.Keyboard);
		}
 protected override void AddItemToCollection(TKey item, ref IDictionary <TKey, TValue> collection, IReorderableListAdaptor adaptor)
 {
     if (!collection.ContainsKey(item))
     {
         collection.Add(item, default(TValue));
     }
 }