//-------------------------------------------------------------------------------------------------- void _BuildCustomRatios() { bool changesFound = false; if (BoxJoint.CustomBoxRatios == null || BoxJoint.CustomBoxRatios.Length != CustomRatioItems.Count) { changesFound = true; } else { for (int i = 0; i < BoxJoint.CustomBoxRatios.Length; i++) { if (BoxJoint.CustomBoxRatios[i] != CustomRatioItems[i].Value) { changesFound = true; break; } } } if (!changesFound) { return; // No changes found } BoxJoint.CustomBoxRatios = CustomRatioItems.Select(item => item.Value).ToArray(); }
//-------------------------------------------------------------------------------------------------- void _CustomRatios_OnSourceUpdated(object sender, DataTransferEventArgs e) { var changedItem = (e.OriginalSource as ValueEditBox)?.Tag as CustomRatioItem; if (changedItem == null || changedItem.Index >= CustomRatioItems.Count) { return; } // Clamp to 100% var sumOfOthers = CustomRatioItems.Sum(item => item.Value) - changedItem.Value - CustomRatioItems[CustomRatioItems.Count - 1].Value; if (sumOfOthers + changedItem.Value > 1.0) { // Clamp to 100% by reducing this value CustomRatioItems[changedItem.Index] = new CustomRatioItem() { Index = changedItem.Index, ReadOnly = false, Value = Math.Max(0.0, 1.0 - sumOfOthers) }; } _ClampLastItem(); _BuildCustomRatios(); }
//-------------------------------------------------------------------------------------------------- void _InitializeCustomRatioItems() { if (BoxJoint.CustomBoxRatios == null) { return; } if (BoxJoint.BoxCount != CustomRatioItems.Count) { CustomRatioItems.Clear(); } // Update for (int i = 0; i < BoxJoint.CustomBoxRatios.Length; i++) { var item = new CustomRatioItem() { Index = i, Value = BoxJoint.CustomBoxRatios[i], ReadOnly = i == BoxJoint.CustomBoxRatios.Length - 1 }; if (CustomRatioItems.Count > i) { CustomRatioItems[i] = item; } else { CustomRatioItems.Add(item); } } }
//-------------------------------------------------------------------------------------------------- public override void Cleanup() { if (BoxJoint != null) { BoxJoint.PropertyChanged -= _BoxJoint_PropertyChanged; } CustomRatioItems.Clear(); }
//-------------------------------------------------------------------------------------------------- void _BoxJoint_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == nameof(BoxJoint.BoxCount)) { if (BoxJoint.CustomBoxRatios == null) { return; } if (BoxJoint.BoxCount <= 1) { return; } int countDiff = BoxJoint.BoxCount - CustomRatioItems.Count; if (countDiff == 0) { return; } if (countDiff > 0) { // New Items double newRatio = CustomRatioItems.Last().Value / (countDiff + 1); for (int i = CustomRatioItems.Count - 1; i < BoxJoint.BoxCount; i++) { var item = new CustomRatioItem() { Index = i, Value = newRatio, ReadOnly = i == CustomRatioItems.Count }; if (i >= CustomRatioItems.Count) { CustomRatioItems.Add(item); } else { CustomRatioItems[i] = item; } } } else { // Lost Items while (CustomRatioItems.Count > BoxJoint.BoxCount) { CustomRatioItems.RemoveAt(CustomRatioItems.Count - 1); } _ClampLastItem(); } _BuildCustomRatios(); } }
//-------------------------------------------------------------------------------------------------- bool _ClampLastItem() { var lastItem = CustomRatioItems[CustomRatioItems.Count - 1]; var sum = CustomRatioItems.Sum(item => item.Value); // Clamp to 100% by adjusting the last value if (sum.IsEqual(1.0, 0.001)) { return(false); // No adjustment needed } CustomRatioItems[CustomRatioItems.Count - 1] = new CustomRatioItem() { Index = lastItem.Index, ReadOnly = true, Value = Math.Max(0.0, 1.0 - (sum - lastItem.Value)) }; return(true); }