using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Linq; using Plugins.Motion.Models; using TeamAAS.Core; using TeamAAS.FlowEngine; using TeamAAS.Motion.Models; namespace Plugins.Motion.Core { /// /// 流程属性面板「轴」下拉:选项来自当前节点已选运动卡的轴配置。 /// public class MotionAxisNoConverter : StringConverter { public override bool GetStandardValuesSupported(ITypeDescriptorContext context) => true; public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) => false; public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { var labels = GetAxes(GetModel(context)) .Select(a => a.Label) .ToList(); // PropertyGridLib 在 Count==0 时不会把属性渲染成下拉;未选卡时给占位项,选卡后由面板刷新/展开时重取。 if (labels.Count == 0) labels.Add("请先选择运动卡"); return new StandardValuesCollection(labels); } internal static MotionAxisModel GetModel(ITypeDescriptorContext context) { if (context?.Instance is MotionAxisModel m) return m; try { return PluginLoader.Instance.SelectFlow?.PluginModel?.GetModel as MotionAxisModel; } catch { return null; } } internal static bool AllowAllAxes(MotionAxisModel model) => model is MotionEnableModel || model is MotionDisableModel || model is MotionStopModel; internal static List<(int No, string Label)> GetAxes(MotionAxisModel model) { var list = new List<(int, string)>(); bool allowAll = AllowAllAxes(model); if (allowAll) list.Add((-1, "-1 全部轴")); string cardName = model?.MotionCardName; if (string.IsNullOrWhiteSpace(cardName)) return list; try { var mgr = CoreManager.Motion; if (mgr == null) return list; var cfg = mgr.Configs?.FirstOrDefault(c => string.Equals(c.Name, cardName, StringComparison.OrdinalIgnoreCase)); if (cfg != null) { foreach (var a in MotionAxisCatalog.GetEffective(cfg)) { if (a == null) continue; list.Add((a.AxisNo, FormatAxis(a.AxisNo, a.Name, a.KindText))); } return list; } var card = mgr.GetMotion(cardName); if (card == null) return list; var axes = card.GetAxes(); if (axes != null && axes.Count > 0) { foreach (var a in axes.OrderBy(x => x.AxisNo)) list.Add((a.AxisNo, FormatAxis(a.AxisNo, a.Name, null))); return list; } for (int i = 0; i < Math.Max(0, card.AxisCount); i++) list.Add((i, FormatAxis(i, $"Axis-{i}", null))); } catch { } return list; } internal static string Format(int axisNo, MotionAxisModel model) { foreach (var a in GetAxes(model)) { if (a.No == axisNo) return a.Label; } return axisNo.ToString(CultureInfo.InvariantCulture); } internal static int Parse(string text, MotionAxisModel model) { if (string.IsNullOrWhiteSpace(text)) return 0; text = text.Trim(); if (text == "请先选择运动卡") return 0; var axes = GetAxes(model); foreach (var a in axes) { if (string.Equals(a.Label, text, StringComparison.OrdinalIgnoreCase)) return a.No; } int space = text.IndexOf(' '); string head = space > 0 ? text.Substring(0, space).Trim() : text; if (int.TryParse(head, NumberStyles.Integer, CultureInfo.InvariantCulture, out int byNo) || int.TryParse(head, NumberStyles.Integer, CultureInfo.CurrentCulture, out byNo)) return byNo; foreach (var a in axes) { var name = AxisNameOf(a.Label); if (!string.IsNullOrEmpty(name) && string.Equals(name, text, StringComparison.OrdinalIgnoreCase)) return a.No; } return 0; } private static string FormatAxis(int no, string name, string kindText) { string n = string.IsNullOrWhiteSpace(name) ? $"Axis-{no}" : name.Trim(); if (string.IsNullOrWhiteSpace(kindText) || kindText == "实轴") return $"{no} {n}"; return $"{no} {n} {kindText}"; } private static string AxisNameOf(string label) { if (string.IsNullOrWhiteSpace(label)) return ""; var parts = label.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); return parts.Length >= 2 ? parts[1] : ""; } } }