private void updateArrangement() { var localPos = ListContainer.ToLocalSpace(screenSpaceDragPosition); int srcIndex = Items.IndexOf(currentlyDraggedItem.Model); // Find the last item with position < mouse position. Note we can't directly use // the item positions as they are being transformed float heightAccumulator = 0; int dstIndex = 0; for (; dstIndex < Items.Count; dstIndex++) { var drawable = itemMap[Items[dstIndex]]; if (!drawable.IsLoaded) { continue; } // Using BoundingBox here takes care of scale, paddings, etc... float height = drawable.BoundingBox.Height; // Rearrangement should occur only after the mid-point of items is crossed heightAccumulator += height / 2; // Check if the midpoint has been crossed (i.e. cursor is located above the midpoint) if (heightAccumulator > localPos.Y) { if (dstIndex > srcIndex) { // Suppose an item is dragged just slightly below its own midpoint. The rearrangement condition (accumulator > pos) will be satisfied for the next immediate item // but not the currently-dragged item, which will invoke a rearrangement. This is an off-by-one condition. // Rearrangement should not occur until the midpoint of the next item is crossed, and so to fix this the next item's index is discarded. dstIndex--; } break; } // Add the remainder of the height of the current item heightAccumulator += height / 2 + ListContainer.Spacing.Y; } dstIndex = Math.Clamp(dstIndex, 0, Items.Count - 1); if (srcIndex == dstIndex) { return; } Items.Move(srcIndex, dstIndex); // Todo: this could be optimised, but it's a very simple iteration over all the items reSort(); }
private void RemoveSegment() { int index = _segments.IndexOf(_selectedSegment); _segments.RemoveAt(index); if (_segments.Count == 0) { SelectedSegment = null; } else { SelectedSegment = index >= _segments.Count ? _segments[index - 1] : _segments[index]; } }
private void EditSoundClass() { var currentNC = _selectedSoundClass.DomainSoundClass as NaturalClass; if (currentNC != null) { var vm = new EditNaturalClassViewModel(_projectService.Project.FeatureSystem, _soundClasses.Select(nc => nc.DomainSoundClass), currentNC); if (_dialogService.ShowModalDialog(this, vm) == true) { var fs = new FeatureStruct(); fs.AddValue(CogFeatureSystem.Type, vm.Type == SoundType.Consonant ? CogFeatureSystem.ConsonantType : CogFeatureSystem.VowelType); foreach (FeatureViewModel feature in vm.ActiveFeatures) { fs.AddValue(feature.DomainFeature, feature.SelectedValue.DomainSymbol); } var newNaturalClass = new SoundClassViewModel(new NaturalClass(vm.Name, fs), _selectedSoundClass.Sonority); int index = _soundClasses.IndexOf(_selectedSoundClass); IsChanged = true; _soundClasses[index] = newNaturalClass; SelectedSoundClass = newNaturalClass; } } else { var currentUnc = _selectedSoundClass.DomainSoundClass as UnnaturalClass; if (currentUnc != null) { var vm = new EditUnnaturalClassViewModel(_dialogService, _projectService.Project.Segmenter, _soundClasses.Select(nc => nc.DomainSoundClass), currentUnc); if (_dialogService.ShowModalDialog(this, vm) == true) { var newUnnaturalClass = new SoundClassViewModel(new UnnaturalClass(vm.Name, vm.Segments, vm.IgnoreModifiers, _projectService.Project.Segmenter), _selectedSoundClass.Sonority); int index = _soundClasses.IndexOf(_selectedSoundClass); IsChanged = true; _soundClasses[index] = newUnnaturalClass; SelectedSoundClass = newUnnaturalClass; } } } }