2009-12-01 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System.Design / System.Windows.Forms.Design / DocumentDesigner.cs
blob14e6aa682d3be1159abc6809278fe2584da7f889
1 //
2 // System.Windows.Forms.Design.DocumentDesigner
3 //
4 // Authors:
5 // Ivan N. Zlatev (contact i-nZ.net)
6 //
7 // (C) 2006-2007 Ivan N. Zlatev
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System;
31 using System.ComponentModel;
32 using System.ComponentModel.Design;
33 using System.Windows.Forms;
34 using System.Drawing;
35 using System.Drawing.Design;
36 using System.Collections;
37 #if NET_2_0
38 using System.Windows.Forms.Design.Behavior;
39 #endif
41 namespace System.Windows.Forms.Design
43 #if NET_2_0
44 [ToolboxItemFilter ("System.Windows.Forms")]
45 #endif
46 public class DocumentDesigner : ScrollableControlDesigner, IRootDesigner, IToolboxUser
49 // This is what you *see*
51 .-------------------------------------.
52 | Panel to host the designed Control |
53 |--------------Splitter---------------|
54 | Panel with a ComponentTray |
55 |_____________________________________|
59 #region DesignerViewFrame
60 public class DesignerViewFrame : System.Windows.Forms.UserControl
62 private System.Windows.Forms.Panel DesignerPanel;
63 private System.Windows.Forms.Splitter splitter1;
64 private System.Windows.Forms.Panel ComponentTrayPanel;
65 private ComponentTray _componentTray;
66 private Control _designedControl;
68 public DesignerViewFrame (Control designedControl, ComponentTray tray)
70 if (designedControl == null) {
71 throw new ArgumentNullException ("designedControl");
73 if (tray == null) {
74 throw new ArgumentNullException ("tray");
77 // The InitializeComponent() call is required for Windows Forms designer support.
79 InitializeComponent();
81 _designedControl = designedControl;
82 this.SuspendLayout ();
83 this.DesignerPanel.Controls.Add (designedControl);
84 this.ResumeLayout ();
86 this.ComponentTray = tray;
89 #region Windows Forms Designer generated code
90 /// <summary>
91 /// This method is required for Windows Forms designer support.
92 /// Do not change the method contents inside the source code editor. The Forms designer might
93 /// not be able to load this method if it was changed manually.
94 /// </summary>
95 private void InitializeComponent() {
96 this.ComponentTrayPanel = new System.Windows.Forms.Panel();
97 this.splitter1 = new System.Windows.Forms.Splitter();
98 this.DesignerPanel = new System.Windows.Forms.Panel();
99 this.SuspendLayout();
101 // ComponentTrayPanel
103 this.ComponentTrayPanel.BackColor = System.Drawing.Color.LemonChiffon;
104 this.ComponentTrayPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
105 this.ComponentTrayPanel.Location = new System.Drawing.Point(0, 194);
106 this.ComponentTrayPanel.Name = "ComponentTrayPanel";
107 this.ComponentTrayPanel.Size = new System.Drawing.Size(292, 72);
108 this.ComponentTrayPanel.TabIndex = 1;
109 this.ComponentTrayPanel.Visible = false;
111 // splitter1
113 this.splitter1.Dock = System.Windows.Forms.DockStyle.Bottom;
114 this.splitter1.Location = new System.Drawing.Point(0, 186);
115 this.splitter1.Name = "splitter1";
116 this.splitter1.Size = new System.Drawing.Size(292, 8);
117 this.splitter1.TabIndex = 2;
118 this.splitter1.TabStop = false;
119 this.splitter1.Visible = false;
121 // DesignerPanel
123 this.DesignerPanel.AutoScroll = true;
124 this.DesignerPanel.BackColor = System.Drawing.Color.White;
125 this.DesignerPanel.Dock = System.Windows.Forms.DockStyle.Fill;
126 this.DesignerPanel.Location = new System.Drawing.Point(0, 0);
127 this.DesignerPanel.Name = "DesignerPanel";
128 this.DesignerPanel.Size = new System.Drawing.Size(292, 266);
129 this.DesignerPanel.TabIndex = 0;
130 this.DesignerPanel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.DesignerPanel_MouseUp);
131 this.DesignerPanel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.DesignerPanel_MouseMove);
132 this.DesignerPanel.MouseDown += new System.Windows.Forms.MouseEventHandler(this.DesignerPanel_MouseDown);
133 this.DesignerPanel.Paint += new PaintEventHandler (DesignerPanel_Paint);
135 // DesignerViewFrame
137 this.Controls.Add(this.splitter1);
138 this.Controls.Add(this.ComponentTrayPanel);
139 this.Controls.Add(this.DesignerPanel);
140 this.Name = "UserControl1";
141 this.Size = new System.Drawing.Size(292, 266);
142 this.Dock = DockStyle.Fill;
143 this.ResumeLayout(false);
146 #endregion
148 private bool _mouseDown = false;
149 private bool _firstMove = false;
151 void DesignerPanel_Paint (object sender, PaintEventArgs e)
153 IUISelectionService selectionServ = this.DesignedControl.Site.GetService (typeof (IUISelectionService)) as IUISelectionService;
154 if (selectionServ != null)
155 selectionServ.PaintAdornments (this.DesignerPanel, e.Graphics);
158 void DesignerPanel_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
160 _mouseDown = true;
161 _firstMove = true;
164 void DesignerPanel_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
166 IUISelectionService selectionServ = this.DesignedControl.Site.GetService (typeof (IUISelectionService)) as IUISelectionService;
167 if (selectionServ == null)
168 return;
170 selectionServ.SetCursor (e.X, e.Y);
171 if (_mouseDown) {
172 if (_firstMove) {
173 selectionServ.MouseDragBegin (this.DesignerPanel, e.X, e.Y);
174 _firstMove = false;
176 else {
177 selectionServ.MouseDragMove (e.X, e.Y);
180 else if (selectionServ.SelectionInProgress) {
181 selectionServ.MouseDragMove (e.X, e.Y);
185 void DesignerPanel_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
187 IUISelectionService selectionServ = this.DesignedControl.Site.GetService (typeof (IUISelectionService)) as IUISelectionService;
188 if (_mouseDown) {
189 if (selectionServ != null)
190 selectionServ.MouseDragEnd (false);
191 _mouseDown = false;
193 else if (selectionServ.SelectionInProgress) {
194 selectionServ.MouseDragEnd (false);
198 // by default the component tray is hidden and essentially should be shown once there
199 // is a component added to it
201 public void ShowComponentTray ()
203 if (!this.ComponentTray.Visible) {
204 this.ComponentTrayPanel.Visible = true;
205 this.ComponentTray.Visible = true;
206 this.splitter1.Visible = true;
210 public void HideComponentTray ()
212 if (!this.ComponentTray.Visible) {
213 this.ComponentTrayPanel.Visible = true;
214 this.ComponentTray.Visible = true;
215 this.splitter1.Visible = true;
219 public ComponentTray ComponentTray {
220 get { return _componentTray; }
221 set {
222 this.SuspendLayout ();
223 this.ComponentTrayPanel.Controls.Remove (_componentTray);
224 this.ComponentTrayPanel.Controls.Add (value);
225 this.ResumeLayout ();
226 _componentTray = value;
227 _componentTray.Visible = false;
231 public Control DesignedControl {
232 get { return _designedControl; }
233 set {
237 protected override void Dispose (bool disposing)
239 if (_designedControl != null) {
240 this.DesignerPanel.Controls.Remove (_designedControl);
241 _designedControl = null;
244 if (_componentTray != null) {
245 this.ComponentTrayPanel.Controls.Remove (_componentTray);
246 _componentTray.Dispose ();
247 _componentTray = null;
250 base.Dispose (disposing);
253 #endregion
258 private DesignerViewFrame _designerViewFrame;
260 public DocumentDesigner ()
264 private DesignerViewFrame View {
265 get { return _designerViewFrame; }
268 #region Initialization
269 public override void Initialize (IComponent component)
271 base.Initialize (component);
273 _designerViewFrame = new DesignerViewFrame (this.Control, new ComponentTray (this, component.Site));
274 _designerViewFrame.DesignedControl.Location = new Point (15, 15);
275 SetValue (this.Component, "Location", new Point (0, 0));
277 IComponentChangeService componentChangeSvc = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
278 if (componentChangeSvc != null) {
279 componentChangeSvc.ComponentAdded += new ComponentEventHandler (OnComponentAdded);
280 componentChangeSvc.ComponentRemoved += new ComponentEventHandler (OnComponentRemoved);
283 IMenuCommandService menuCommands = GetService (typeof (IMenuCommandService)) as IMenuCommandService;
284 IServiceContainer serviceContainer = this.GetService (typeof (IServiceContainer)) as IServiceContainer;
285 if (menuCommands != null && serviceContainer != null)
286 new DefaultMenuCommands (serviceContainer).AddTo (menuCommands);
287 InitializeSelectionService ();
290 private void InitializeSelectionService ()
292 IUISelectionService guiSelectionService = this.GetService (typeof (IUISelectionService)) as IUISelectionService;
293 if (guiSelectionService == null) {
294 IServiceContainer serviceContainer = this.GetService (typeof (IServiceContainer)) as IServiceContainer;
295 serviceContainer.AddService (typeof (IUISelectionService), (IUISelectionService) new UISelectionService (serviceContainer));
298 ISelectionService selectionService = this.GetService (typeof (ISelectionService)) as ISelectionService;
299 selectionService.SetSelectedComponents (new IComponent[] { this.Component });
302 #if !NET_2_0
303 // MSDN says overriden
305 public override void OnSetComponentDefaults ()
307 base.OnSetComponentDefaults ();
309 #endif
311 protected override void Dispose (bool disposing)
313 if (disposing) {
314 if (_designerViewFrame != null) {
315 _designerViewFrame.Dispose ();
316 _designerViewFrame = null;
319 IComponentChangeService componentChangeSvc = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
320 if (componentChangeSvc != null) {
321 componentChangeSvc.ComponentAdded -= new ComponentEventHandler (OnComponentAdded);
322 componentChangeSvc.ComponentRemoved -= new ComponentEventHandler (OnComponentRemoved);
325 base.Dispose (disposing);
327 #endregion
330 #region MSDN says overriden
332 #if NET_2_0
333 public override GlyphCollection GetGlyphs (GlyphSelectionType selectionType)
335 return base.GetGlyphs (selectionType);
337 #endif
339 protected override void WndProc (ref Message m)
341 base.WndProc (ref m);
344 protected override void OnContextMenu (int x, int y)
346 base.OnContextMenu (x, y);
349 protected override void OnCreateHandle ()
351 base.OnCreateHandle ();
354 #endregion
357 #region Components and ComponentTray
359 private void OnComponentAdded (object sender, ComponentEventArgs args)
361 if (!(args.Component is Control)) {
362 this.View.ComponentTray.AddComponent (args.Component);
363 if (this.View.ComponentTray.ComponentCount > 0) {
364 if (!this.View.ComponentTray.Visible)
365 this.View.ShowComponentTray ();
370 private void OnComponentRemoved (object sender, ComponentEventArgs args)
372 if (!(args.Component is Control)) {
373 this.View.ComponentTray.RemoveComponent (args.Component);
374 if (this.View.ComponentTray.ComponentCount == 0) {
375 if (this.View.ComponentTray.Visible)
376 this.View.HideComponentTray ();
380 #endregion
383 #region IRootDesigner
385 object IRootDesigner.GetView (ViewTechnology technology)
387 #if NET_2_0
388 if (technology != ViewTechnology.Default)
389 throw new ArgumentException ("Only ViewTechnology.WindowsForms is supported.");
390 #else
391 if (technology != ViewTechnology.WindowsForms)
392 throw new ArgumentException ("Only ViewTechnology.WindowsForms is supported.");
393 #endif
394 return _designerViewFrame;
397 ViewTechnology[] IRootDesigner.SupportedTechnologies {
398 get {
399 #if NET_2_0
400 return new ViewTechnology[] { ViewTechnology.Default };
401 #else
402 return new ViewTechnology[] { ViewTechnology.WindowsForms };
403 #endif
406 #endregion
409 #region IToolBoxUser
411 // Indicates whether the specified tool is supported by the designer.
412 // If it is not the tool is disabled in the toolbox.
414 // Used for subclasses, e.g the FormDocumentDesigner won't accept a Form?
416 bool IToolboxUser.GetToolSupported (ToolboxItem tool)
418 return this.GetToolSupported (tool);
421 protected virtual bool GetToolSupported (ToolboxItem tool)
423 return true;
427 // Handles the behavior that occurs when a user double-clicks a toolbox item.
429 void IToolboxUser.ToolPicked (ToolboxItem tool)
431 this.ToolPicked (tool);
434 // ToolPicked is called when the user double-clicks on a toolbox item.
435 // The document designer should create a component for the specified tool.
436 // Only tools that are enabled in the toolbox will be passed to this method.
438 // I create the component in the parent container of the primary selection.
439 // If not available I create it in the rootcomponent (this essentially :-) )
441 protected virtual void ToolPicked (ToolboxItem tool)
443 ISelectionService selectionSvc = GetService (typeof (ISelectionService)) as ISelectionService;
444 IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
445 if (selectionSvc != null && host != null) {
446 IDesigner designer = host.GetDesigner ((IComponent) selectionSvc.PrimarySelection);
447 if (designer is ParentControlDesigner)
448 ParentControlDesigner.InvokeCreateTool ((ParentControlDesigner) designer, tool);
449 else
450 this.CreateTool (tool);
452 else {
453 this.CreateTool (tool);
455 IToolboxService tbServ = this.GetService (typeof (IToolboxService)) as IToolboxService;
456 tbServ.SelectedToolboxItemUsed ();
458 #endregion
461 #region Properties
462 // A root designer can be resized to the bottom and to the right.
464 public override SelectionRules SelectionRules {
465 get {
466 return (SelectionRules.RightSizeable | SelectionRules.BottomSizeable | SelectionRules.Visible);
469 #endregion
472 #region Metadata filtering and Design-Time properties
474 // MSDN says that this adds the "BackColor" and "Location" browsable design-time propeties.
476 // The reason for overwriting the Location property created by the ControDesigner is that
477 // the root component is not draggable (e.g a form has a static location in the DesignerViewFrame)
479 protected override void PreFilterProperties (IDictionary properties)
481 base.PreFilterProperties (properties);
483 PropertyDescriptor propertyDescriptor = properties["BackColor"] as PropertyDescriptor;
484 if (propertyDescriptor != null) {
485 properties["BackColor"] = TypeDescriptor.CreateProperty (typeof (DocumentDesigner),
486 propertyDescriptor,
487 new Attribute[] { new DefaultValueAttribute (System.Drawing.SystemColors.Control) });
490 propertyDescriptor = properties["Location"] as PropertyDescriptor;
491 if (propertyDescriptor != null) {
492 properties["Location"] = TypeDescriptor.CreateProperty (typeof (DocumentDesigner),
493 propertyDescriptor,
494 new Attribute[] { new DefaultValueAttribute (typeof (Point), "0, 0") });
498 private Color BackColor {
499 get { return (Color) ShadowProperties["BackColor"]; }
500 set {
501 ShadowProperties["BackColor"] = value;
502 this.Control.BackColor = value;
506 private Point Location {
507 get { return (Point) ShadowProperties["Location"]; }
508 set { ShadowProperties["Location"] = value; }
510 #endregion
513 #region Misc
514 protected IMenuEditorService menuEditorService;
516 // Checks for the existence of a menu editor service and creates one if one does not already exist.
517 // component - The IComponent to ensure has a context menu service.
518 // XXX: Not sure exactly what this should do...
520 protected virtual void EnsureMenuEditorService (IComponent component)
522 if (this.menuEditorService == null && component is ContextMenu)
523 menuEditorService = (IMenuEditorService) GetService (typeof (IMenuEditorService));
525 #endregion