using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; #if WEB_SERVICE #else using System.Drawing.Design; #endif using System.Linq; using System.Xml.Serialization; using DevExpress.XtraVerticalGrid; using GeoSigma; using GeoSigma.SigmaDrawerStyle; using GeoSigmaDrawLib; using SigmaDrawerStyle; namespace SigmaDrawerElement { /// /// The drawer text. /// [TypeConverter(typeof(PropertySorter))] public class DrawerText : ElementBase, ICustomTypeDescriptor { /// /// 属性类别排序 /// private List categorys = new List() { "基础属性", "文本", "对齐方式", "其他", "杂项" }; /// /// Initializes a new instance of the class. /// public DrawerText() { ElementType = DrawElementType.ELEMENT_TEXT; } /// /// Gets or sets the name. /// [XmlAttribute("Name")] [Category("基础属性"), DisplayName("名称"), Browsable(false), PropertyOrder(0)] public override string Name { get => base.Name; set => base.Name = value; } [Category("文本"), DisplayName("坐标"), PropertyOrder(1)] [XmlElement("Coordinate")] [TypeConverter(typeof(GeoSigma.SigmaDrawerStyle.Converter.BaseExpandableConverter))] public DrawerCoordinateXYZ Coordinate { get; set; } = new DrawerCoordinateXYZ(); [XmlIgnore] [Category("文本"), DisplayName("文字大小"), PropertyOrder(2)] public double Height { get => Other.Height; //set => Other.Height = value; set { if (Math.Abs(this.Height - value) < 1E-5 || value == 0) { return; } //if (this.SizeScaleFix == true) //{ if (this.Width == 0 || this.Height == 0) { this.Other.Height = value; return; } double dFactor = this.Width / this.Height; this.Other.Width = value * dFactor; this.Other.Height = value; //} //else //{ // this.Other.Height = value; //} } } #region Font [Browsable(false)] [XmlElement("Font")] public LogFont NameFont { get; set; } = LogFont.Default; private Font _TextFont; [XmlIgnore] [Category("文本"), DisplayName("字体"), PropertyOrder(3)] [TypeConverter(typeof(FontPropertyConvert))] public Font TextFont { get { _TextFont = Font.FromLogFont(NameFont); return _TextFont; } set { _TextFont = value; NameFont = LogFontConverter.convert(_TextFont); } } #endregion [Browsable(false)] [XmlAttribute("Color")] public int ColorRef; [XmlIgnore] #if WEB_SERVICE #else [Editor(typeof(PropertyEditorColor), typeof(UITypeEditor))] #endif [Category("文本"), DisplayName("颜色"), PropertyOrder(4)] public Color LineColor { get { return ColorTranslator.FromWin32(ColorRef); } set { ColorRef = ColorTranslator.ToWin32(value); } } [XmlIgnore] [Category("文本"), DisplayName("角度"), PropertyOrder(5)] public double Angle { get => Other.Angle; set => Other.Angle = value; } [XmlIgnore] [Category("文本"), DisplayName("文字边框"), PropertyOrder(6)] [TypeConverter(typeof(GeoSigma.SigmaDrawerStyle.Converter.BorderTypeConverter))] public int BorderType { get { return Other.Style & (int)TextStyleFlags.frameAll; } set { Other.Style &= ~(int)TextStyleFlags.frameAll; Other.Style |= value; } } [Browsable(false)] [XmlElement("Other")] [TypeConverter(typeof(GeoSigma.SigmaDrawerStyle.Converter.BaseExpandableConverter))] public TxOther Other { get; set; } = new TxOther(); [XmlIgnore] [Category("文本"), DisplayName("文字宽度"), Browsable(false), PropertyOrder(0)] public double Width { get => Other.Width; set { if (Math.Abs(this.Width - value) < 1E-5 || value == 0) { return; } if (this.SizeScaleFix == true) { if (this.Width == 0 || this.Height == 0) { this.Other.Width = value; return; } double dFactor = this.Height / this.Width; this.Other.Height = value * dFactor; this.Other.Width = value; } else { this.Other.Width = value; } } } public bool sizeScaleFix = true; [XmlIgnore] [Category("文本"), DisplayName("固定高宽比"), Browsable(false)] [TypeConverter(typeof(GeoSigma.SigmaDrawerStyle.Converter.YesNoConverter))] public bool SizeScaleFix { get => sizeScaleFix; set => sizeScaleFix = value; } [XmlIgnore] [Category("文本"), DisplayName("显示上下标"), Browsable(false)] [TypeConverter(typeof(GeoSigma.SigmaDrawerStyle.Converter.YesNoConverter))] public bool Script { get => Other.Script == 1; set => Other.Script = value ? 1 : 0; } [XmlIgnore] [Category("对齐方式"), DisplayName("水平对齐"), PropertyOrder(6)] [TypeConverter(typeof(GeoSigma.SigmaDrawerStyle.Converter.AlignHorizionMultConverter))] public int AlignHorizion { get { int nStyle = Other.AlignMul; return nStyle; //int nStyle = Other.Style & (int)TextStyleFlags.alignAllH; //if (nStyle == (int)TextStyleFlags.alignRight) //{ // return (int)TextStyleFlags.alignLeftMult; //} //else if (nStyle == ((int)TextStyleFlags.alignRight | (int)TextStyleFlags.alignLeftMult)) //{ // nStyle = (int)TextStyleFlags.alignLeftMult; //} //else if (nStyle == ((int)TextStyleFlags.alignRight | (int)TextStyleFlags.alignCenterMult)) //{ // nStyle = (int)TextStyleFlags.alignCenterMult; //} //else if (nStyle == ((int)TextStyleFlags.alignRight | (int)TextStyleFlags.alignRightMult)) //{ // nStyle = (int)TextStyleFlags.alignRightMult; //} //return nStyle; } set { Other.Style &= ~(int)TextStyleFlags.alignAllMult; Other.Style |= value; } } [XmlIgnore] [Category("对齐方式"), DisplayName("\t\t垂直对齐"),Browsable(false)] [TypeConverter(typeof(GeoSigma.SigmaDrawerStyle.Converter.AlignVerticalConverter))] public int AlignVertical { get { return Other.Style & (int)TextStyleFlags.alignAllV; } set { Other.Style &= ~(int)TextStyleFlags.alignAllV; Other.Style |= value; } } #region String public class TxString { [XmlAttribute] public int Line { get => Items.Count; set { } // 这个空 set 不能删除,否则 xml 序列化时将无法生成 Line 属性 } public class TxsItem { [XmlAttribute] public string Value { get; set; } } [Browsable(false)] [XmlElement("Item")] [TypeConverter(typeof(GeoSigma.SigmaDrawerStyle.Converter.BaseCollectionConverter))] public List Items { get; set; } = new List(); public override string ToString() { return string.Join(string.Empty, Items.Select(r => r.Value)); } } [Category("其他"), DisplayName("内容"), ReadOnly(true)] [XmlElement("String")] public TxString String { get; set; } = new TxString(); // 增加一个隐藏开关 (选中多个文本时) [XmlIgnore] [Browsable(false)] public bool IsMultiSelectMode { get; set; } = false; #endregion #region ICustomTypeDescriptor 接口实现 //选中多个文本时 public PropertyDescriptorCollection GetProperties(Attribute[] attributes) { // 获取默认的全部属性(包含从 ElementBase 继承来的图层等属性) PropertyDescriptorCollection baseProps = TypeDescriptor.GetProperties(this, true); // 如果不是多选模式,正常显示所有属性 if (!IsMultiSelectMode) return baseProps; // 如果是多选模式,进行精确过滤 List newProps = new List(); foreach (PropertyDescriptor pd in baseProps) { bool shouldHide = false; // 隐藏“其他”下的“内容” (变量名为 String,显示名为 内容) if (pd.Name == "String" || pd.DisplayName == "内容") shouldHide = true; // 隐藏“图层” (变量名可能叫 Layer,显示名为 图层) if (pd.Name == "Layer" || pd.DisplayName == "图层") shouldHide = true; // 隐藏“文本”下的“坐标” (变量名为 Coordinate,显示名为 坐标) if (pd.Name == "Coordinate" || pd.DisplayName == "坐标") shouldHide = true; // 如果不需要隐藏,就加到新的列表中显示出来 if (!shouldHide) { newProps.Add(pd); } } return new PropertyDescriptorCollection(newProps.ToArray()); } // 下面这些是接口必带的套路代码,直接原样放着即可 public PropertyDescriptorCollection GetProperties() => GetProperties(new Attribute[0]); public AttributeCollection GetAttributes() => TypeDescriptor.GetAttributes(this, true); public string GetClassName() => TypeDescriptor.GetClassName(this, true); public string GetComponentName() => TypeDescriptor.GetComponentName(this, true); public TypeConverter GetConverter() => TypeDescriptor.GetConverter(this, true); public EventDescriptor GetDefaultEvent() => TypeDescriptor.GetDefaultEvent(this, true); public PropertyDescriptor GetDefaultProperty() => TypeDescriptor.GetDefaultProperty(this, true); public object GetEditor(Type editorBaseType) => TypeDescriptor.GetEditor(this, editorBaseType, true); public EventDescriptorCollection GetEvents(Attribute[] attributes) => TypeDescriptor.GetEvents(this, attributes, true); public EventDescriptorCollection GetEvents() => TypeDescriptor.GetEvents(this, true); public object GetPropertyOwner(PropertyDescriptor pd) => this; #endregion } #region Other public class TxOther { [XmlAttribute] public double Height { get; set; } [XmlAttribute] public double Width { get; set; } [XmlAttribute] public double Angle { get; set; } /// /// 纵向输入是否启用 /// [XmlAttribute] public bool VerticalInput { get; set; } = false; private int style = (int)(TextStyleFlags.alignLeftMult | TextStyleFlags.alignBottom | TextStyleFlags.frameNull); [XmlAttribute] public int Style { get { return style; } set { style = value; int nPos = style & (int)TextStyleFlags.alignAllPosition; if (nPos > 0) { PositionH = nPos; } int nAlignH = style & (int)TextStyleFlags.alignAllMult; if (nAlignH > 0) { AlignMul = nAlignH; } } } /// /// 水平对齐 /// [XmlIgnore] public int AlignMul { get; set; } = (int)TextStyleFlags.alignLeftMult; private int positionH = (int)TextStyleFlags.alignRight; /// /// 水平位置 /// [XmlIgnore] public int PositionH { get { return positionH; } set { positionH = value; } } [XmlAttribute] public int Script { get; set; } } #endregion }