In .:
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ContainerControl.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2004 Novell, Inc.
21 //
22 // Authors:
23 //      Peter Bartok    pbartok@novell.com
24 //
25 //
26
27
28 // NOT COMPLETE
29
30 using System.ComponentModel;
31 using System.ComponentModel.Design;
32 using System.Drawing;
33
34 namespace System.Windows.Forms {
35         public class ContainerControl : ScrollableControl, IContainerControl {
36                 private Control         active_control;
37                 private Control         focused_control;
38                 private Control         unvalidated_control;
39 #if NET_2_0
40                 private SizeF           auto_scale_dimensions;
41                 private AutoScaleMode   auto_scale_mode;
42 #endif
43
44                 #region Public Constructors
45                 public ContainerControl() {
46                         active_control = null;
47                         focused_control = null;
48                         unvalidated_control = null;
49                         ControlRemoved += new ControlEventHandler(OnControlRemoved);
50 #if NET_2_0
51                         auto_scale_dimensions = SizeF.Empty;
52                         auto_scale_mode = AutoScaleMode.None;
53 #endif
54                 }
55                 #endregion      // Public Constructors
56
57                 #region Public Instance Properties
58                 [Browsable (false)]
59                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
60                 public Control ActiveControl {
61                         get {
62                                 return active_control;
63                         }
64
65                         set {
66                                 if ((active_control==value) || (value==null)) {
67                                         return;
68                                 }
69
70                                 active_control = value;
71
72                                 if (!Contains(value) && this != value) {
73                                         throw new ArgumentException("Not a child control");
74                                 }
75
76                                 if (this is Form)
77                                         CheckAcceptButton();
78                                 
79                                 // Scroll control into view
80
81                                 // Let the control know it's selected
82                                 Select(value);
83                         }
84                 }
85
86 #if NET_2_0
87                 public SizeF AutoScaleDimensions {
88                         get {
89                                 return auto_scale_dimensions;
90                         }
91
92                         set {
93                                 auto_scale_dimensions = value;
94                         }
95                 }
96
97                 public SizeF AutoScaleFactor {
98                         get {
99                                 if (auto_scale_dimensions.IsEmpty) {
100                                         return new SizeF(1f, 1f);
101                                 }
102                                 return new SizeF(CurrentAutoScaleDimensions.Width / auto_scale_dimensions.Width, 
103                                         CurrentAutoScaleDimensions.Height / auto_scale_dimensions.Height);
104                         }
105                 }
106
107
108                 [MonoTODO("Call scaling method")]
109                 public virtual AutoScaleMode AutoScaleMode {
110                         get {
111                                 return auto_scale_mode;
112                         }
113                         set {
114                                 if (auto_scale_mode != value) {
115                                         auto_scale_mode = value;
116
117                                         // Trigger scaling
118                                 }
119                         }
120                 }
121 #endif // NET_2_0
122
123                 [Browsable (false)]
124                 public override BindingContext BindingContext {
125                         get {
126                                 if (base.BindingContext == null) {
127                                         base.BindingContext = new BindingContext();
128                                 }
129                                 return base.BindingContext;
130                         }
131
132                         set {
133                                 base.BindingContext = value;
134                         }
135                 }
136
137 #if NET_2_0
138                 [MonoTODO("Revisit when System.Drawing.GDI.WindowsGraphics.GetTextMetrics is done or come up with other cross-plat avg. font width calc method")]
139                 public SizeF CurrentAutoScaleDimensions {
140                         get {
141                                 switch(auto_scale_mode) {
142                                         case AutoScaleMode.Dpi: {
143                                                 Bitmap          bmp;
144                                                 Graphics        g;
145                                                 SizeF           size;
146
147                                                 bmp = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
148                                                 g = Graphics.FromImage(bmp);
149                                                 size = new SizeF(g.DpiX, g.DpiY);
150                                                 g.Dispose();
151                                                 bmp.Dispose();
152                                                 return size;
153                                         }
154
155                                         case AutoScaleMode.Font: {
156                                                 // http://msdn2.microsoft.com/en-us/library/system.windows.forms.containercontrol.currentautoscaledimensions(VS.80).aspx
157                                                 // Implement System.Drawing.GDI.WindowsGraphics.GetTextMetrics first...
158                                                 break;
159                                         }
160                                 }
161
162                                 return auto_scale_dimensions;
163                         }
164                 }
165 #endif
166
167                 [Browsable (false)]
168                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
169                 public Form ParentForm {
170                         get {
171                                 Control parent;
172
173                                 parent = this.parent;
174
175                                 while (parent != null) {
176                                         if (parent is Form) {
177                                                 return (Form)parent;
178                                         }
179                                         parent = parent.parent;
180                                 }
181
182                                 return null;
183                         }
184                 }
185                 #endregion      // Public Instance Properties
186
187                 #region Protected Instance Methods
188                 protected override CreateParams CreateParams {
189                         get {
190                                 return base.CreateParams;
191                         }
192                 }
193                 #endregion      // Public Instance Methods
194
195                 #region Public Instance Methods
196                 [MonoTODO]
197                 static bool ValidateWarned;
198                 public bool Validate() {
199                         //throw new NotImplementedException();
200                         if (!ValidateWarned) {
201                                 Console.WriteLine("ContainerControl.Validate is not yet implemented");
202                                 ValidateWarned = true;
203                         }
204                         return true;
205                 }
206
207                 bool IContainerControl.ActivateControl(Control control) {
208                         return Select(control);
209                 }
210                 #endregion      // Public Instance Methods
211
212                 #region Protected Instance Methods
213                 [EditorBrowsable (EditorBrowsableState.Advanced)]
214                 protected override void AdjustFormScrollbars(bool displayScrollbars) {
215                         base.AdjustFormScrollbars(displayScrollbars);
216                 }
217
218                 protected override void Dispose(bool disposing) {
219                         base.Dispose(disposing);
220                 }
221
222                 // LAMESPEC This used to be documented, but it's not in code 
223                 // and no longer listed in MSDN2
224                 // [EditorBrowsable (EditorBrowsableState.Advanced)]
225                 // protected override void OnControlRemoved(ControlEventArgs e) {
226                 private void OnControlRemoved(object sender, ControlEventArgs e) {
227                         if (e.Control == this.unvalidated_control) {
228                                 this.unvalidated_control = null;
229                         }
230
231                         if (e.Control == this.active_control) {
232                                 this.unvalidated_control = null;
233                         }
234
235                         // base.OnControlRemoved(e);
236                 }
237
238                 protected override void OnCreateControl() {
239                         base.OnCreateControl();
240                         // MS seems to call this here, it gets the whole databinding process started
241                         OnBindingContextChanged (EventArgs.Empty);
242                 }
243
244                 [EditorBrowsable (EditorBrowsableState.Advanced)]
245                 protected override bool ProcessDialogChar(char charCode) {
246                         if (GetTopLevel()) {
247                                 if (ProcessMnemonic(charCode)) {
248                                         return true;
249                                 }
250                         }
251                         return base.ProcessDialogChar(charCode);
252                 }
253
254                 protected override bool ProcessDialogKey(Keys keyData) {
255                         Keys    key;
256                         bool    forward;
257
258                         key = keyData & Keys.KeyCode;
259                         forward = true;
260
261                         switch (key) {
262                                 case Keys.Tab: {
263                                         if (ProcessTabKey((Control.ModifierKeys & Keys.Shift) == 0)) {
264                                                 return true;
265                                         }
266                                         break;
267                                 }
268
269                                 case Keys.Left: {
270                                         forward = false;
271                                         goto case Keys.Down;
272                                 }
273
274                                 case Keys.Up: {
275                                         forward = false;
276                                         goto case Keys.Down;
277                                 }
278
279                                 case Keys.Right: {
280                                         goto case Keys.Down;
281                                 }
282                                 case Keys.Down: {
283                                         if (SelectNextControl(active_control, forward, false, false, true)) {
284                                                 return true;
285                                         }
286                                         break;
287                                 } 
288
289
290                         }
291                         return base.ProcessDialogKey(keyData);
292                 }
293
294                 protected override bool ProcessMnemonic(char charCode) {
295                         bool    wrapped;
296                         Control c;
297
298                         wrapped = false;
299                         c = active_control;
300
301                         do {
302                                 c = GetNextControl(c, true);
303                                 if (c != null) {
304                                         // This is stupid. I want to be able to call c.ProcessMnemonic directly
305                                         if (c.ProcessControlMnemonic(charCode)) {
306                                                 return(true);
307                                         }
308                                         continue;
309                                 } else {
310                                         if (wrapped) {
311                                                 break;
312                                         }
313                                         wrapped = true;
314                                 }
315                         } while (c != active_control);
316                         
317                         return false;
318                 }
319
320                 protected virtual bool ProcessTabKey(bool forward) {
321                         return SelectNextControl(active_control, forward, true, true, true);
322                 }
323
324                 protected override void Select(bool directed, bool forward) {
325                         base.Select(directed, forward);
326                 }
327
328                 protected virtual void UpdateDefaultButton() {
329                         // MS Internal
330                 }
331
332                 [EditorBrowsable (EditorBrowsableState.Advanced)]
333                 protected override void WndProc(ref Message m) {
334                         base.WndProc(ref m);
335                 }
336                 #endregion      // Protected Instance Methods
337                 
338                 internal virtual void CheckAcceptButton()
339                 {
340                         // do nothing here, only called if it is a Form
341                 }
342         }
343 }