//------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //------------------------------------------------------------------------------ using System; using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing; using System.Diagnostics; using System.Globalization; using System.Web.UI.Design; using System.Web.UI.Design.MobileControls; using System.Web.UI.MobileControls; using System.Web.UI.MobileControls.Adapters; namespace System.Web.UI.Design.MobileControls.Adapters { [ System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode) ] [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")] internal static class DesignerAdapterUtil { // margin width is 10px on right (10px on left taken care of by parentChildOffset) private const int _marginWidth = 10; // default Panel or Form width private const int _defaultContainerWidth = 300; // 11px on the left and the right for padding and margin between levels private const int _marginPerLevel = 22; // offset of control within a template is 10px on the left + 11px on the right + 1 private const int _templateParentChildOffset = 22; // offset of control outside of a template is 11px private const int _regularParentChildOffset = 11; // default width for controls in templates. The value doesn't matter as long as it is // equal or larger than parent width, since the parent control designer will still // truncate to 100% internal const int CONTROL_MAX_WIDTH_IN_TEMPLATE = 300; internal const byte CONTROL_IN_TEMPLATE_NONEDIT = 0x01; internal const byte CONTROL_IN_TEMPLATE_EDIT = 0x02; internal static IDesigner ControlDesigner(IComponent component) { Debug.Assert(null != component); ISite compSite = component.Site; if (compSite != null) { return ((IDesignerHost) compSite.GetService(typeof(IDesignerHost))).GetDesigner(component); } return null; } internal static ContainmentStatus GetContainmentStatus(Control control) { ContainmentStatus containmentStatus = ContainmentStatus.Unknown; Control parent = control.Parent; if (control == null || parent == null) { return containmentStatus; } if (parent is Form) { containmentStatus = ContainmentStatus.InForm; } else if (parent is Panel) { containmentStatus = ContainmentStatus.InPanel; } else if (parent is Page || parent is UserControl) { containmentStatus = ContainmentStatus.AtTopLevel; } else if (InTemplateFrame(control)) { containmentStatus = ContainmentStatus.InTemplateFrame; } return containmentStatus; } internal static IComponent GetRootComponent(IComponent component) { Debug.Assert(null != component); ISite compSite = component.Site; if (compSite != null) { IDesignerHost host = (IDesignerHost)compSite.GetService(typeof(IDesignerHost)); if (host != null) { return host.RootComponent; } } return null; } internal static String GetWidth(Control control) { if (DesignerAdapterUtil.GetContainmentStatus(control) == ContainmentStatus.AtTopLevel) { return Constants.ControlSizeAtToplevelInNonErrorMode; } return Constants.ControlSizeInContainer; } internal static bool InMobilePage(Control control) { return (control != null && control.Page is MobilePage); } internal static bool InUserControl(IComponent component) { return GetRootComponent(component) is UserControl; } internal static bool InMobileUserControl(IComponent component) { return GetRootComponent(component) is MobileUserControl; } // Returns true if the closest templateable ancestor is in template editing mode. internal static bool InTemplateFrame(Control control) { if (control.Parent == null) { return false; } TemplatedControlDesigner designer = ControlDesigner(control.Parent) as TemplatedControlDesigner; if (designer == null) { return InTemplateFrame(control.Parent); } if (designer.InTemplateMode) { return true; } return false; } internal static void AddAttributesToProperty( Type designerType, IDictionary properties, String propertyName, Attribute[] attributeArray) { Debug.Assert (propertyName != null && propertyName.Length != 0); PropertyDescriptor prop = (PropertyDescriptor)properties[propertyName]; Debug.Assert(prop != null); prop = TypeDescriptor.CreateProperty ( designerType, prop, attributeArray); properties[propertyName] = prop; } internal static void AddAttributesToPropertiesOfDifferentType( Type designerType, Type newType, IDictionary properties, String propertyName, Attribute newAttribute) { Debug.Assert (propertyName != null && propertyName.Length != 0); PropertyDescriptor prop = (PropertyDescriptor)properties[propertyName]; Debug.Assert(prop != null); // we can't create the designer DataSource property based on the runtime property since their // types do not match. Therefore, we have to copy over all the attributes from the runtime // and use them that way. System.ComponentModel.AttributeCollection runtimeAttributes = prop.Attributes; Attribute[] attrs = new Attribute[runtimeAttributes.Count + 1]; runtimeAttributes.CopyTo(attrs, 0); attrs[runtimeAttributes.Count] = newAttribute; prop = TypeDescriptor.CreateProperty ( designerType, propertyName, newType, attrs); properties[propertyName] = prop; } internal static int NestingLevel(Control control, out bool inTemplate, out int defaultControlWidthInTemplate) { int level = -1; defaultControlWidthInTemplate = 0; inTemplate = false; if (control != null) { Control parent = control.Parent; while (parent != null) { level++; IDesigner designer = ControlDesigner(parent); if (designer is MobileTemplatedControlDesigner) { defaultControlWidthInTemplate = ((MobileTemplatedControlDesigner) designer).TemplateWidth - _templateParentChildOffset; inTemplate = true; return level; } parent = parent.Parent; } } return level; } internal static void SetStandardStyleAttributes(IHtmlControlDesignerBehavior behavior, ContainmentStatus containmentStatus) { if (behavior == null) { return; } bool controlAtTopLevel = (containmentStatus == ContainmentStatus.AtTopLevel); Color cw = SystemColors.Window; Color ct = SystemColors.WindowText; Color c = Color.FromArgb((Int16)(ct.R * 0.1 + cw.R * 0.9), (Int16)(ct.G * 0.1 + cw.G * 0.9), (Int16)(ct.B * 0.1 + cw.B * 0.9)); behavior.SetStyleAttribute("borderColor", true, ColorTranslator.ToHtml(c), true); behavior.SetStyleAttribute("borderStyle", true, "solid", true); behavior.SetStyleAttribute("borderWidth", true, "1px", true); behavior.SetStyleAttribute("marginLeft", true, "5px", true); behavior.SetStyleAttribute("marginRight", true, controlAtTopLevel ? "30%" : "5px", true); behavior.SetStyleAttribute("marginTop", true, controlAtTopLevel ? "5px" : "2px", true); behavior.SetStyleAttribute("marginBottom", true, controlAtTopLevel ? "5px" : "2px", true); } internal static String GetDesignTimeErrorHtml( String errorMessage, bool infoMode, Control control, IHtmlControlDesignerBehavior behavior, ContainmentStatus containmentStatus) { String id = String.Empty; Debug.Assert(control != null, "control is null"); if (control.Site != null) { id = control.Site.Name; } if (behavior != null) { behavior.SetStyleAttribute("borderWidth", true, "0px", true); } return String.Format(CultureInfo.CurrentCulture, MobileControlDesigner.defaultErrorDesignTimeHTML, new Object[] { control.GetType().Name, id, errorMessage, infoMode? MobileControlDesigner.infoIcon : MobileControlDesigner.errorIcon, ((containmentStatus == ContainmentStatus.AtTopLevel) ? Constants.ControlSizeAtToplevelInErrormode : Constants.ControlSizeInContainer) }); } internal static int GetMaxWidthToFit(MobileControl control, out byte templateStatus) { IDesigner parentDesigner = ControlDesigner(control.Parent); IDesigner controlDesigner = ControlDesigner(control); int defaultControlWidthInTemplate; NativeMethods.IHTMLElement2 htmlElement2Parent = null; if (controlDesigner == null) { templateStatus = CONTROL_IN_TEMPLATE_NONEDIT; return 0; } Debug.Assert(controlDesigner is MobileControlDesigner || controlDesigner is MobileTemplatedControlDesigner, "controlDesigner is not MobileControlDesigner or MobileTemplatedControlDesigner"); templateStatus = 0x00; if (parentDesigner is MobileTemplatedControlDesigner) { htmlElement2Parent = (NativeMethods.IHTMLElement2) ((MobileTemplatedControlDesigner) parentDesigner).DesignTimeElementInternal; } else if (parentDesigner is MobileContainerDesigner) { htmlElement2Parent = (NativeMethods.IHTMLElement2) ((MobileContainerDesigner) parentDesigner).DesignTimeElementInternal; } bool inTemplate; int nestingLevel = DesignerAdapterUtil.NestingLevel(control, out inTemplate, out defaultControlWidthInTemplate); if (inTemplate) { templateStatus = CONTROL_IN_TEMPLATE_EDIT; } if (htmlElement2Parent != null) { int maxWidth; if (!inTemplate) { Debug.Assert(control.Parent is MobileControl); Style parentStyle = ((MobileControl) control.Parent).Style; Alignment alignment = (Alignment) parentStyle[Style.AlignmentKey, true]; int parentChildOffset=0; // AUI 2786 if (alignment != Alignment.NotSet && alignment != Alignment.Left) { parentChildOffset = _regularParentChildOffset; } else { NativeMethods.IHTMLRectCollection rectColl = null; NativeMethods.IHTMLRect rect = null; int index = 0; Object obj = index; NativeMethods.IHTMLElement2 htmlElement2; if (controlDesigner is MobileControlDesigner) { htmlElement2 = (NativeMethods.IHTMLElement2) ((MobileControlDesigner) controlDesigner).DesignTimeElementInternal; } else { htmlElement2 = (NativeMethods.IHTMLElement2) ((MobileTemplatedControlDesigner) controlDesigner).DesignTimeElementInternal; } if (null == htmlElement2) { return 0; } try { rectColl = htmlElement2.GetClientRects(); } catch (Exception) { // this happens when switching from Design view to HTML view return 0; } if( rectColl.GetLength() >= 1) { rect = (NativeMethods.IHTMLRect)rectColl.Item(ref obj); parentChildOffset = rect.GetLeft(); rectColl = htmlElement2Parent.GetClientRects(); //Debug.Assert(rectColl.GetLength() == 1); rect = (NativeMethods.IHTMLRect) rectColl.Item(ref obj); parentChildOffset -= rect.GetLeft(); } } maxWidth = GetLength(htmlElement2Parent) - _marginWidth - parentChildOffset; if (maxWidth > 0 && maxWidth > _defaultContainerWidth - nestingLevel * _marginPerLevel) { maxWidth = _defaultContainerWidth - nestingLevel * _marginPerLevel; } } else { int parentWidth = GetLength(htmlElement2Parent); if (parentWidth == 0) { // AUI 4525 maxWidth = defaultControlWidthInTemplate; } else { maxWidth = parentWidth - _templateParentChildOffset; } if (maxWidth > 0 && maxWidth > defaultControlWidthInTemplate - nestingLevel * _marginPerLevel) { maxWidth = defaultControlWidthInTemplate - nestingLevel * _marginPerLevel; } } return maxWidth; } return 0; } private static int GetLength(NativeMethods.IHTMLElement2 element) { NativeMethods.IHTMLRectCollection rectColl = element.GetClientRects(); //Debug.Assert(rectColl.GetLength() == 1); Object obj = rectColl.GetLength() - 1; NativeMethods.IHTMLRect rect = (NativeMethods.IHTMLRect)rectColl.Item(ref obj); return rect.GetRight() - rect.GetLeft(); } } }