public ConfigElementLabelPresent(AddToConfigWindow window, string targetLabel) { var uxmlPath = k_UxmlDir + "ConfigElementLabelPresent.uxml"; AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(uxmlPath).CloneTree(this); labelElement = this.Q <Label>("config-name"); var removeButton = this.Q <Button>("remove-from-config-button"); removeButton.text = "Remove Label"; var openButton = this.Q <Button>("open-config-button"); openButton.clicked += () => { Selection.SetActiveObjectWithContext(labelConfig, null); }; removeButton.clicked += () => { var editor = Editor.CreateEditor(labelConfig); if (editor is SemanticSegmentationLabelConfigEditor semanticEditor) { semanticEditor.RemoveLabel(targetLabel); } else if (editor is IdLabelConfigEditor idEditor) { idEditor.RemoveLabel(targetLabel); } window.RefreshLists(); Object.DestroyImmediate(editor); }; }
public ConfigElementLabelNotPresent(AddToConfigWindow window, List <string> targetLabels) { var uxmlPath = k_UxmlDir + "ConfigElementLabelPresent.uxml"; AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(uxmlPath).CloneTree(this); labelElement = this.Q <Label>("config-name"); var addButton = this.Q <Button>("remove-from-config-button"); addButton.text = targetLabels.Count == 1 ? "Add Label" : "Add All Labels"; var openButton = this.Q <Button>("open-config-button"); openButton.clicked += () => { Selection.SetActiveObjectWithContext(labelConfig, null); }; addButton.clicked += () => { var editor = Editor.CreateEditor(labelConfig); if (editor is SemanticSegmentationLabelConfigEditor semanticEditor) { foreach (var label in targetLabels) { semanticEditor.AddLabel(label); } } else if (editor is IdLabelConfigEditor idEditor) { foreach (var label in targetLabels) { idEditor.AddLabel(label); } } if (targetLabels.Count > 1) { window.SetStatus("All Labels Added to " + labelConfig.name); } window.RefreshLists(); Object.DestroyImmediate(editor); }; }
public AddedLabelEditor(LabelingEditor editor, ListView listView) { var uxmlPath = m_UxmlDir + "AddedLabelElement.uxml"; AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(uxmlPath).CloneTree(this); labelTextField = this.Q <TextField>("label-value"); var removeButton = this.Q <Button>("remove-button"); var addToConfigButton = this.Q <Button>("add-to-config-button"); labelTextField.isDelayed = true; labelTextField.RegisterValueChangedCallback((cEvent) => { //Do not let the user define a duplicate label if (editor.CommonLabels.Contains(cEvent.newValue) && editor.CommonLabels.IndexOf(cEvent.newValue) != indexInList) { //The listview recycles child visual elements and that causes the RegisterValueChangedCallback event to be called when scrolling. //Therefore, we need to make sure we are not in this code block just because of scrolling, but because the user is actively changing one of the labels. //The editor.CommonLabels.IndexOf(cEvent.newValue) != m_IndexInList check is for this purpose. Debug.LogError("A label with the string " + cEvent.newValue + " has already been added to selected objects."); editor.ChangesHappeningInForeground = true; editor.RefreshManualLabelingData(); return; } bool shouldRefresh = false; foreach (var targetObject in editor.targets) { if (targetObject is Labeling labeling) { var indexToModifyInTargetLabelList = labeling.labels.IndexOf(editor.CommonLabels[indexInList]); var serializedLabelingObject2 = new SerializedObject(labeling); var serializedLabelArray2 = serializedLabelingObject2.FindProperty(nameof(Labeling.labels)); serializedLabelArray2.GetArrayElementAtIndex(indexToModifyInTargetLabelList).stringValue = cEvent.newValue; shouldRefresh = shouldRefresh || serializedLabelArray2.serializedObject.hasModifiedProperties; serializedLabelingObject2.ApplyModifiedProperties(); serializedLabelingObject2.SetIsDifferentCacheDirty(); } } //the value change event is called even when the listview recycles its child elements for re-use during scrolling, therefore, we should check to make sure there are modified properties, otherwise we would be doing the refresh for no reason (reduces scrolling performance) if (shouldRefresh) { editor.ChangesHappeningInForeground = true; editor.RefreshManualLabelingData(); } }); addToConfigButton.clicked += () => { AddToConfigWindow.ShowWindow(labelTextField.value); }; removeButton.clicked += () => { List <string> commonLabels = new List <string>(); commonLabels.Clear(); var firstTarget = editor.targets[0] as Labeling; if (firstTarget != null) { commonLabels.AddRange(firstTarget.labels); foreach (var obj in editor.targets) { commonLabels = commonLabels.Intersect(((Labeling)obj).labels).ToList(); } foreach (var targetObject in editor.targets) { if (targetObject is Labeling labeling) { RemoveLabelFromLabelingSerObj(labeling, commonLabels); } } editor.serializedObject.SetIsDifferentCacheDirty(); editor.RefreshManualLabelingData(); } }; }
void OnEnable() { m_LabelConfigTypes = AddToConfigWindow.FindAllSubTypes(typeof(LabelConfig <>)); var mySerializedObject = new SerializedObject(serializedObject.targetObjects[0]); m_Labeling = mySerializedObject.targetObject as Labeling; m_UxmlPath = m_UxmlDir + "Labeling_Main.uxml"; m_Root = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(m_UxmlPath).CloneTree(); m_CurrentLabelsListView = m_Root.Q <ListView>("current-labels-listview"); m_SuggestedLabelsListViewFromName = m_Root.Q <ListView>("suggested-labels-name-listview"); m_SuggestedLabelsListViewFromPath = m_Root.Q <ListView>("suggested-labels-path-listview"); m_LabelConfigsScrollView = m_Root.Q <ScrollView>("label-configs-scrollview"); m_SuggestedOnNamePanel = m_Root.Q <VisualElement>("suggested-labels-from-name"); m_SuggestedOnPathPanel = m_Root.Q <VisualElement>("suggested-labels-from-path"); m_AddButton = m_Root.Q <Button>("add-label"); m_CurrentAutoLabel = m_Root.Q <Label>("current-auto-label"); m_CurrentAutoLabelTitle = m_Root.Q <Label>("current-auto-label-title"); m_AutoLabelingToggle = m_Root.Q <Toggle>("auto-or-manual-toggle"); m_ManualLabelingContainer = m_Root.Q <VisualElement>("manual-labeling"); m_AutoLabelingContainer = m_Root.Q <VisualElement>("automatic-labeling"); m_FromLabelConfigsContainer = m_Root.Q <VisualElement>("from-label-configs"); m_SuggestedLabelsContainer = m_Root.Q <VisualElement>("suggested-labels"); m_AddAutoLabelToConfButton = m_Root.Q <Button>("add-auto-label-to-config"); m_AddManualLabelsTitle = m_Root.Q <Label>("add-manual-labels-title"); var dropdownParent = m_Root.Q <VisualElement>("drop-down-parent"); m_ItIsPossibleToAddMultipleAutoLabelsToConfig = false; InitializeLabelingSchemes(dropdownParent); AssesAutoLabelingStatus(); m_FirstItemLabelsArray = serializedObject.FindProperty(nameof(Labeling.labels)); if (serializedObject.targetObjects.Length > 1) { var addedTitle = m_Root.Q <Label>("added-labels-title"); addedTitle.text = "Common Labels of Selected Items"; m_SuggestedOnNamePanel.style.display = DisplayStyle.None; m_AddAutoLabelToConfButton.text = "Add Automatic Labels of All Selected Assets to Config..."; } else { m_AddAutoLabelToConfButton.text = "Add to Label Config..."; } m_AddAutoLabelToConfButton.clicked += () => { AddToConfigWindow.ShowWindow(CreateUnionOfAllLabels().ToList()); }; m_AddButton.clicked += () => { var labelsUnion = CreateUnionOfAllLabels(); var newLabel = FindNewLabelValue(labelsUnion); foreach (var targetObject in targets) { if (targetObject is Labeling labeling) { var serializedLabelingObject2 = new SerializedObject(labeling); var serializedLabelArray2 = serializedLabelingObject2.FindProperty(nameof(Labeling.labels)); serializedLabelArray2.InsertArrayElementAtIndex(serializedLabelArray2.arraySize); serializedLabelArray2.GetArrayElementAtIndex(serializedLabelArray2.arraySize - 1).stringValue = newLabel; serializedLabelingObject2.ApplyModifiedProperties(); serializedLabelingObject2.SetIsDifferentCacheDirty(); serializedObject.SetIsDifferentCacheDirty(); } } ChangesHappeningInForeground = true; RefreshManualLabelingData(); }; m_AutoLabelingToggle.RegisterValueChangedCallback(evt => { AutoLabelToggleChanged(); }); ChangesHappeningInForeground = true; m_Root.schedule.Execute(CheckForModelChanges).Every(30); }