public override void OnGUI(Rect rect) { if (elements == null) { return; } using (new EditorGUILayout.HorizontalScope(EditorStyles.toolbar, GUILayout.Height(15f))) { if (GUILayout.Button(toolbarPlusIcon, EditorStyles.toolbarButton, GUILayout.Width(50f))) { elements.Add(elementType.GetDefaultValue()); OnUpdateElements(); } GUILayout.FlexibleSpace(); } using (var scrollViewScope = new EditorGUILayout.ScrollViewScope(scrollPosition)) { var removeIndexs = new List <int>(); for (var i = 0; i < elements.Count; i++) { using (new EditorGUILayout.HorizontalScope()) { EditorGUI.BeginChangeCheck(); elements[i] = EditorRecordFieldUtility.DrawRecordField(elements[i], elementType); if (EditorGUI.EndChangeCheck()) { OnUpdateElements(); } if (GUILayout.Button(toolbarMinusIcon, GUILayout.Width(20f))) { removeIndexs.Add(i); } } } if (removeIndexs.Any()) { foreach (var removeIndex in removeIndexs) { elements.RemoveAt(removeIndex); } OnUpdateElements(); } scrollPosition = scrollViewScope.scrollPosition; } }
public void SetContents(Type type, object value) { this.arrayType = type; this.elementType = EditorRecordFieldUtility.GetDisplayType(type); var list = new ArrayList(); foreach (var item in (IEnumerable)value) { list.Add(item); } elements = list.Cast <object>().ToList(); }
protected override float GetCustomRowHeight(int row, TreeViewItem treeViewItem) { var item = treeViewItem as RecordViewItem; var valueNames = masterController.GetValueNames(); var customRowHeight = 0f; for (var i = 0; i < valueNames.Length; i++) { var valueName = valueNames[i]; if (!multiColumnHeader.IsColumnVisible(i)) { continue; } var valueType = masterController.GetValueType(valueName); if (valueType == typeof(string)) { var value = masterController.GetValue(item.Record, valueName) as string; var hight = EditorRecordFieldUtility.GetTextFieldHight(value); if (customRowHeight < hight) { customRowHeight = hight; if (EditorGUIUtility.singleLineHeight < customRowHeight) { customRowHeight += 4f; } } } } return(RowHight < customRowHeight ? customRowHeight : RowHight); }
protected override void DrawContent(int index, object content) { var current = Event.current; var valueNames = masterController.GetValueNames(); var fieldAreaInfos = new List <Tuple <Rect, string> >(); using (new EditorGUILayout.HorizontalScope()) { for (var i = 0; i < valueNames.Length; i++) { var valueName = valueNames[i]; var value = masterController.GetValue(content, valueName); var valueType = masterController.GetValueType(valueName); Action <object> onUpdateValue = x => { masterController.UpdateValue(content, valueName, x); if (onChangeRecord != null) { onChangeRecord.OnNext(Unit.Default); } }; var color = masterController.IsChanged(content, valueName) ? Color.yellow : Color.white; var fieldWidth = masterController.FieldWidth[i]; using (new BackgroundColorScope(color)) { if (EditorRecordFieldUtility.IsArrayType(valueType)) { var builder = new StringBuilder(); foreach (var item in (IEnumerable)value) { builder.AppendFormat("{0},", item); } var text = builder.ToString().TrimEnd(','); GUILayout.Label(text, EditorStyles.textField, GUILayout.Width(fieldWidth)); var fieldRect = GUILayoutUtility.GetLastRect(); // メニュー表示と干渉するのでGUILayout.Buttonを使わない. if (fieldRect.Contains(current.mousePosition) && current.type == EventType.MouseDown && current.button == 0) { var mouseRect = new Rect(current.mousePosition, Vector2.one); var arrayFieldPopupWindow = new ArrayFieldPopupWindow(); arrayFieldPopupWindow.SetContents(valueType, value); arrayFieldPopupWindow.OnUpdateElementsAsObservable() .Subscribe(x => onUpdateValue(x)) .AddTo(lifetimeDisposable.Disposable); PopupWindow.Show(mouseRect, arrayFieldPopupWindow); current.Use(); } } else { EditorGUI.BeginChangeCheck(); value = EditorRecordFieldUtility.DrawRecordField(value, valueType, GUILayout.Width(fieldWidth)); if (EditorGUI.EndChangeCheck()) { onUpdateValue(value); } } fieldAreaInfos.Add(Tuple.Create(GUILayoutUtility.GetLastRect(), valueName)); } } } // 右クリックでメニュー表示. if (current.type == EventType.MouseDown && current.button == 1) { var fieldAreaInfo = fieldAreaInfos.FirstOrDefault(x => x.Item1.Contains(current.mousePosition)); if (fieldAreaInfo != null) { var valueName = fieldAreaInfo.Item2; if (masterController.IsChanged(content, valueName)) { var menu = new GenericMenu(); GenericMenu.MenuFunction onResetMenuClick = () => { masterController.ResetValue(content, valueName); }; menu.AddItem(new GUIContent("Reset"), false, onResetMenuClick); menu.ShowAsContext(); current.Use(); } } } }
public bool IsChanged(object record, string valueName) { var originData = changedRecords.GetValueOrDefault(record); if (originData == null) { return(false); } var valueType = GetValueType(valueName); var interfaces = valueType.GetInterfaces(); var originValue = GetValue(originData, valueName); var currentValue = GetValue(record, valueName); if (interfaces.Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable <>))) { var originArray = new ArrayList(); var currentArray = new ArrayList(); foreach (var item in (IEnumerable)originValue) { originArray.Add(item); } foreach (var item in (IEnumerable)currentValue) { currentArray.Add(item); } if (originArray.Count != currentArray.Count) { return(true); } for (var i = 0; i < originArray.Count; i++) { var v1 = originArray[i]; var v2 = currentArray[i]; if (!Equals(v1, v2)) { return(true); } } return(false); } if (valueType.IsGenericType) { if (valueType.GetGenericTypeDefinition() == typeof(Nullable <>)) { var displayType = EditorRecordFieldUtility.GetDisplayType(valueType); if (originValue == null) { originValue = displayType.GetDefaultValue(); } if (currentValue == null) { currentValue = displayType.GetDefaultValue(); } } } return(originValue == null ? currentValue != null : !originValue.Equals(currentValue)); }
private void DrawFieldGUI(Rect rect, string valueName, object record) { var current = Event.current; var value = masterController.GetValue(record, valueName); var valueType = masterController.GetValueType(valueName); Action <object> onUpdateValue = x => { masterController.UpdateValue(record, valueName, x); if (onChangeRecord != null) { onChangeRecord.OnNext(Unit.Default); } RefreshCustomRowHeights(); }; var color = masterController.IsChanged(record, valueName) ? EditedColor : Color.white; rect.height = EditorGUIUtility.singleLineHeight; using (new BackgroundColorScope(color)) { if (EditorRecordFieldUtility.IsArrayType(valueType)) { var builder = new StringBuilder(); if (value != null) { foreach (var item in (IEnumerable)value) { builder.AppendFormat("{0},", item); } } var text = builder.ToString().TrimEnd(','); EditorGUI.LabelField(rect, text, EditorStyles.textField); if (MasterController.CanEdit || !string.IsNullOrEmpty(text)) { // メニュー表示と干渉するのでGUILayout.Buttonを使わない. if (rect.Contains(current.mousePosition) && current.type == EventType.MouseDown && current.button == 0) { var mouseRect = new Rect(current.mousePosition, Vector2.one); var arrayFieldPopupWindow = new ArrayFieldPopupWindow(); arrayFieldPopupWindow.SetContents(valueType, value); arrayFieldPopupWindow.OnUpdateElementsAsObservable() .Subscribe(x => onUpdateValue(x)) .AddTo(lifetimeDisposable.Disposable); PopupWindow.Show(mouseRect, arrayFieldPopupWindow); current.Use(); } } } else { if (valueType == typeof(string)) { rect.height = EditorRecordFieldUtility.GetTextFieldHight(value as string); } EditorGUI.BeginChangeCheck(); try { value = EditorRecordFieldUtility.DrawField(rect, value, valueType); } catch (Exception e) { Debug.LogErrorFormat("Error: {0}\nValueName = {1}\nValueType = {2}\nValue = {3}\n", e.Message, valueName, valueType, value); } if (EditorGUI.EndChangeCheck() && MasterController.CanEdit) { onUpdateValue(value); } } } // 右クリックでメニュー表示. if (rect.Contains(current.mousePosition) && current.type == EventType.MouseDown && current.button == 1) { if (masterController.IsChanged(record, valueName)) { var menu = new GenericMenu(); GenericMenu.MenuFunction onResetMenuClick = () => { masterController.ResetValue(record, valueName); }; menu.AddItem(new GUIContent("Reset"), false, onResetMenuClick); menu.ShowAsContext(); GUI.FocusControl(string.Empty); current.Use(); } } }