1 //------------------------------------------------------------------------------ 2 // <copyright file="DesignerAdapterUtil.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 //------------------------------------------------------------------------------ 6 7 using System; 8 using System.Collections; 9 using System.ComponentModel; 10 using System.ComponentModel.Design; 11 using System.Drawing; 12 using System.Diagnostics; 13 using System.Globalization; 14 using System.Web.UI.Design; 15 using System.Web.UI.Design.MobileControls; 16 using System.Web.UI.MobileControls; 17 using System.Web.UI.MobileControls.Adapters; 18 19 namespace System.Web.UI.Design.MobileControls.Adapters 20 { 21 [ 22 System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, 23 Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode) 24 ] 25 [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.")] 26 internal static class DesignerAdapterUtil 27 { 28 // margin width is 10px on right (10px on left taken care of by parentChildOffset) 29 private const int _marginWidth = 10; 30 // default Panel or Form width 31 private const int _defaultContainerWidth = 300; 32 // 11px on the left and the right for padding and margin between levels 33 private const int _marginPerLevel = 22; 34 // offset of control within a template is 10px on the left + 11px on the right + 1 35 private const int _templateParentChildOffset = 22; 36 // offset of control outside of a template is 11px 37 private const int _regularParentChildOffset = 11; 38 39 // default width for controls in templates. The value doesn't matter as long as it is 40 // equal or larger than parent width, since the parent control designer will still 41 // truncate to 100% 42 internal const int CONTROL_MAX_WIDTH_IN_TEMPLATE = 300; 43 internal const byte CONTROL_IN_TEMPLATE_NONEDIT = 0x01; 44 internal const byte CONTROL_IN_TEMPLATE_EDIT = 0x02; 45 ControlDesigner(IComponent component)46 internal static IDesigner ControlDesigner(IComponent component) 47 { 48 Debug.Assert(null != component); 49 ISite compSite = component.Site; 50 51 if (compSite != null) 52 { 53 return ((IDesignerHost) compSite.GetService(typeof(IDesignerHost))).GetDesigner(component); 54 } 55 return null; 56 } 57 GetContainmentStatus(Control control)58 internal static ContainmentStatus GetContainmentStatus(Control control) 59 { 60 ContainmentStatus containmentStatus = ContainmentStatus.Unknown; 61 Control parent = control.Parent; 62 63 if (control == null || parent == null) 64 { 65 return containmentStatus; 66 } 67 68 if (parent is Form) 69 { 70 containmentStatus = ContainmentStatus.InForm; 71 } 72 else if (parent is Panel) 73 { 74 containmentStatus = ContainmentStatus.InPanel; 75 } 76 else if (parent is Page || parent is UserControl) 77 { 78 containmentStatus = ContainmentStatus.AtTopLevel; 79 } 80 else if (InTemplateFrame(control)) 81 { 82 containmentStatus = ContainmentStatus.InTemplateFrame; 83 } 84 85 return containmentStatus; 86 } 87 GetRootComponent(IComponent component)88 internal static IComponent GetRootComponent(IComponent component) 89 { 90 Debug.Assert(null != component); 91 ISite compSite = component.Site; 92 93 if (compSite != null) 94 { 95 IDesignerHost host = (IDesignerHost)compSite.GetService(typeof(IDesignerHost)); 96 if (host != null) 97 { 98 return host.RootComponent; 99 } 100 } 101 102 return null; 103 } 104 GetWidth(Control control)105 internal static String GetWidth(Control control) 106 { 107 if (DesignerAdapterUtil.GetContainmentStatus(control) == ContainmentStatus.AtTopLevel) 108 { 109 return Constants.ControlSizeAtToplevelInNonErrorMode; 110 } 111 return Constants.ControlSizeInContainer; 112 } 113 InMobilePage(Control control)114 internal static bool InMobilePage(Control control) 115 { 116 return (control != null && control.Page is MobilePage); 117 } 118 InUserControl(IComponent component)119 internal static bool InUserControl(IComponent component) 120 { 121 return GetRootComponent(component) is UserControl; 122 } 123 InMobileUserControl(IComponent component)124 internal static bool InMobileUserControl(IComponent component) 125 { 126 return GetRootComponent(component) is MobileUserControl; 127 } 128 129 // Returns true if the closest templateable ancestor is in template editing mode. InTemplateFrame(Control control)130 internal static bool InTemplateFrame(Control control) 131 { 132 if (control.Parent == null) 133 { 134 return false; 135 } 136 137 TemplatedControlDesigner designer = 138 ControlDesigner(control.Parent) as TemplatedControlDesigner; 139 140 if (designer == null) 141 { 142 return InTemplateFrame(control.Parent); 143 } 144 145 if (designer.InTemplateMode) 146 { 147 return true; 148 } 149 150 return false; 151 } 152 AddAttributesToProperty( Type designerType, IDictionary properties, String propertyName, Attribute[] attributeArray)153 internal static void AddAttributesToProperty( 154 Type designerType, 155 IDictionary properties, 156 String propertyName, 157 Attribute[] attributeArray) 158 { 159 Debug.Assert (propertyName != null && 160 propertyName.Length != 0); 161 162 PropertyDescriptor prop = (PropertyDescriptor)properties[propertyName]; 163 Debug.Assert(prop != null); 164 165 prop = TypeDescriptor.CreateProperty ( 166 designerType, 167 prop, 168 attributeArray); 169 170 properties[propertyName] = prop; 171 } 172 AddAttributesToPropertiesOfDifferentType( Type designerType, Type newType, IDictionary properties, String propertyName, Attribute newAttribute)173 internal static void AddAttributesToPropertiesOfDifferentType( 174 Type designerType, 175 Type newType, 176 IDictionary properties, 177 String propertyName, 178 Attribute newAttribute) 179 { 180 Debug.Assert (propertyName != null && 181 propertyName.Length != 0); 182 183 PropertyDescriptor prop = (PropertyDescriptor)properties[propertyName]; 184 Debug.Assert(prop != null); 185 186 // we can't create the designer DataSource property based on the runtime property since their 187 // types do not match. Therefore, we have to copy over all the attributes from the runtime 188 // and use them that way. 189 System.ComponentModel.AttributeCollection runtimeAttributes = prop.Attributes; 190 Attribute[] attrs = new Attribute[runtimeAttributes.Count + 1]; 191 runtimeAttributes.CopyTo(attrs, 0); 192 193 attrs[runtimeAttributes.Count] = newAttribute; 194 prop = TypeDescriptor.CreateProperty ( 195 designerType, 196 propertyName, 197 newType, 198 attrs); 199 200 properties[propertyName] = prop; 201 } 202 NestingLevel(Control control, out bool inTemplate, out int defaultControlWidthInTemplate)203 internal static int NestingLevel(Control control, 204 out bool inTemplate, 205 out int defaultControlWidthInTemplate) 206 { 207 int level = -1; 208 defaultControlWidthInTemplate = 0; 209 inTemplate = false; 210 if (control != null) 211 { 212 Control parent = control.Parent; 213 while (parent != null) 214 { 215 level++; 216 IDesigner designer = ControlDesigner(parent); 217 if (designer is MobileTemplatedControlDesigner) 218 { 219 defaultControlWidthInTemplate = 220 ((MobileTemplatedControlDesigner) designer).TemplateWidth - 221 _templateParentChildOffset; 222 inTemplate = true; 223 return level; 224 } 225 parent = parent.Parent; 226 } 227 } 228 return level; 229 } 230 SetStandardStyleAttributes(IHtmlControlDesignerBehavior behavior, ContainmentStatus containmentStatus)231 internal static void SetStandardStyleAttributes(IHtmlControlDesignerBehavior behavior, 232 ContainmentStatus containmentStatus) 233 { 234 if (behavior == null) { 235 return; 236 } 237 238 bool controlAtTopLevel = (containmentStatus == ContainmentStatus.AtTopLevel); 239 240 Color cw = SystemColors.Window; 241 Color ct = SystemColors.WindowText; 242 Color c = Color.FromArgb((Int16)(ct.R * 0.1 + cw.R * 0.9), 243 (Int16)(ct.G * 0.1 + cw.G * 0.9), 244 (Int16)(ct.B * 0.1 + cw.B * 0.9)); 245 behavior.SetStyleAttribute("borderColor", true, ColorTranslator.ToHtml(c), true); 246 behavior.SetStyleAttribute("borderStyle", true, "solid", true); 247 248 behavior.SetStyleAttribute("borderWidth", true, "1px", true); 249 behavior.SetStyleAttribute("marginLeft", true, "5px", true); 250 behavior.SetStyleAttribute("marginRight", true, controlAtTopLevel ? "30%" : "5px", true); 251 behavior.SetStyleAttribute("marginTop", true, controlAtTopLevel ? "5px" : "2px", true); 252 behavior.SetStyleAttribute("marginBottom", true, controlAtTopLevel ? "5px" : "2px", true); 253 } 254 GetDesignTimeErrorHtml( String errorMessage, bool infoMode, Control control, IHtmlControlDesignerBehavior behavior, ContainmentStatus containmentStatus)255 internal static String GetDesignTimeErrorHtml( 256 String errorMessage, 257 bool infoMode, 258 Control control, 259 IHtmlControlDesignerBehavior behavior, 260 ContainmentStatus containmentStatus) 261 { 262 String id = String.Empty; 263 Debug.Assert(control != null, "control is null"); 264 265 if (control.Site != null) 266 { 267 id = control.Site.Name; 268 } 269 270 if (behavior != null) { 271 behavior.SetStyleAttribute("borderWidth", true, "0px", true); 272 } 273 274 return String.Format(CultureInfo.CurrentCulture, 275 MobileControlDesigner.defaultErrorDesignTimeHTML, 276 new Object[] 277 { 278 control.GetType().Name, 279 id, 280 errorMessage, 281 infoMode? MobileControlDesigner.infoIcon : MobileControlDesigner.errorIcon, 282 ((containmentStatus == ContainmentStatus.AtTopLevel) ? 283 Constants.ControlSizeAtToplevelInErrormode : 284 Constants.ControlSizeInContainer) 285 }); 286 } 287 GetMaxWidthToFit(MobileControl control, out byte templateStatus)288 internal static int GetMaxWidthToFit(MobileControl control, out byte templateStatus) 289 { 290 IDesigner parentDesigner = ControlDesigner(control.Parent); 291 IDesigner controlDesigner = ControlDesigner(control); 292 int defaultControlWidthInTemplate; 293 294 NativeMethods.IHTMLElement2 htmlElement2Parent = null; 295 296 if (controlDesigner == null) 297 { 298 templateStatus = CONTROL_IN_TEMPLATE_NONEDIT; 299 return 0; 300 } 301 Debug.Assert(controlDesigner is MobileControlDesigner || 302 controlDesigner is MobileTemplatedControlDesigner, 303 "controlDesigner is not MobileControlDesigner or MobileTemplatedControlDesigner"); 304 305 templateStatus = 0x00; 306 if (parentDesigner is MobileTemplatedControlDesigner) 307 { 308 htmlElement2Parent = 309 (NativeMethods.IHTMLElement2) 310 ((MobileTemplatedControlDesigner) parentDesigner).DesignTimeElementInternal; 311 } 312 else if (parentDesigner is MobileContainerDesigner) 313 { 314 htmlElement2Parent = 315 (NativeMethods.IHTMLElement2) 316 ((MobileContainerDesigner) parentDesigner).DesignTimeElementInternal; 317 } 318 319 bool inTemplate; 320 int nestingLevel = DesignerAdapterUtil.NestingLevel(control, out inTemplate, out defaultControlWidthInTemplate); 321 if (inTemplate) 322 { 323 templateStatus = CONTROL_IN_TEMPLATE_EDIT; 324 } 325 326 if (htmlElement2Parent != null) 327 { 328 int maxWidth; 329 if (!inTemplate) 330 { 331 Debug.Assert(control.Parent is MobileControl); 332 Style parentStyle = ((MobileControl) control.Parent).Style; 333 Alignment alignment = (Alignment) parentStyle[Style.AlignmentKey, true]; 334 int parentChildOffset=0; 335 336 // AUI 2786 337 if (alignment != Alignment.NotSet && alignment != Alignment.Left) 338 { 339 parentChildOffset = _regularParentChildOffset; 340 } 341 else 342 { 343 NativeMethods.IHTMLRectCollection rectColl = null; 344 NativeMethods.IHTMLRect rect = null; 345 int index = 0; 346 Object obj = index; 347 348 NativeMethods.IHTMLElement2 htmlElement2; 349 350 if (controlDesigner is MobileControlDesigner) 351 { 352 htmlElement2 = (NativeMethods.IHTMLElement2) ((MobileControlDesigner) controlDesigner).DesignTimeElementInternal; 353 } 354 else 355 { 356 htmlElement2 = (NativeMethods.IHTMLElement2) ((MobileTemplatedControlDesigner) controlDesigner).DesignTimeElementInternal; 357 } 358 359 if (null == htmlElement2) 360 { 361 return 0; 362 } 363 364 try 365 { 366 rectColl = htmlElement2.GetClientRects(); 367 } 368 catch (Exception) 369 { 370 // this happens when switching from Design view to HTML view 371 return 0; 372 } 373 374 if( rectColl.GetLength() >= 1) 375 { 376 rect = (NativeMethods.IHTMLRect)rectColl.Item(ref obj); 377 parentChildOffset = rect.GetLeft(); 378 379 rectColl = htmlElement2Parent.GetClientRects(); 380 //Debug.Assert(rectColl.GetLength() == 1); 381 rect = (NativeMethods.IHTMLRect) rectColl.Item(ref obj); 382 parentChildOffset -= rect.GetLeft(); 383 } 384 } 385 386 maxWidth = GetLength(htmlElement2Parent) - _marginWidth - parentChildOffset; 387 if (maxWidth > 0 && maxWidth > _defaultContainerWidth - nestingLevel * _marginPerLevel) 388 { 389 maxWidth = _defaultContainerWidth - nestingLevel * _marginPerLevel; 390 } 391 } 392 else 393 { 394 int parentWidth = GetLength(htmlElement2Parent); 395 if (parentWidth == 0) 396 { 397 // AUI 4525 398 maxWidth = defaultControlWidthInTemplate; 399 } 400 else 401 { 402 maxWidth = parentWidth - _templateParentChildOffset; 403 } 404 405 if (maxWidth > 0 && maxWidth > defaultControlWidthInTemplate - nestingLevel * _marginPerLevel) 406 { 407 maxWidth = defaultControlWidthInTemplate - nestingLevel * _marginPerLevel; 408 } 409 } 410 return maxWidth; 411 } 412 return 0; 413 } 414 GetLength(NativeMethods.IHTMLElement2 element)415 private static int GetLength(NativeMethods.IHTMLElement2 element) { 416 NativeMethods.IHTMLRectCollection rectColl = element.GetClientRects(); 417 //Debug.Assert(rectColl.GetLength() == 1); 418 Object obj = rectColl.GetLength() - 1; 419 NativeMethods.IHTMLRect rect = (NativeMethods.IHTMLRect)rectColl.Item(ref obj); 420 return rect.GetRight() - rect.GetLeft(); 421 } 422 } 423 } 424