* ImageList.cs: When the image stream is set pull all the images
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / PropertyGridView.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) 2005 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //      Jonathan Chambers       (jonathan.chambers@ansys.com)
24 //
25 //
26
27 // NOT COMPLETE
28
29 using System;
30 using System.Drawing;
31
32 namespace System.Windows.Forms.PropertyGridInternal
33 {
34         public class PropertyGridView : System.Windows.Forms.ScrollableControl
35         {
36                 internal const int LEFT_COLUMN_WIDTH = 16;
37                 internal const int ROW_HEIGHT = 16;
38                 internal const int RESIZE_WIDTH = 3;
39                 private TextBox grid_textbox;
40                 internal PropertyGrid property_grid;
41                 internal bool redraw;
42                 internal bool resizing_grid;
43                 internal int label_column_width;
44
45                 public PropertyGridView(PropertyGrid property_grid)
46                 {
47                         this.property_grid = property_grid;
48                         this.BackColor = Color.Beige;
49                         grid_textbox = new TextBox();
50
51                         grid_textbox.Visible = false;
52                         grid_textbox.Font = new Font(this.Font,FontStyle.Bold);
53                         grid_textbox.BorderStyle = BorderStyle.None;
54                         grid_textbox.BackColor = this.BackColor;
55                         grid_textbox.Validated += new EventHandler(grid_textbox_Validated);
56
57                         label_column_width = 65;
58                         resizing_grid = false;
59
60                         this.Controls.Add(grid_textbox);
61
62                         ForeColorChanged+=new EventHandler(RedrawEvent);
63                         BackColorChanged+=new System.EventHandler(RedrawEvent);
64                         FontChanged+=new EventHandler(RedrawEvent);
65                         SizeChanged+=new EventHandler(RedrawEvent);
66                         MouseMove+=new MouseEventHandler(PropertyGridView_MouseMove);
67                         
68                         SetStyle(ControlStyles.UserPaint, true);
69                         SetStyle(ControlStyles.AllPaintingInWmPaint, true);
70                         SetStyle(ControlStyles.ResizeRedraw, true);
71                         SetStyle(ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, false);
72                 }
73
74                 protected override void OnPaint(PaintEventArgs pevent)
75                 {
76                         this.grid_textbox.Visible = false;
77                         Draw(pevent);
78                         pevent.Graphics.DrawImage(this.ImageBuffer, pevent.ClipRectangle, pevent.ClipRectangle, GraphicsUnit.Pixel);
79                         if (property_grid.SelectedGridItem != null)
80                                 grid_textbox.Visible = true;
81                         base.OnPaint (pevent);
82                 }
83
84                 // Derived classes should override Draw method and we dont want
85                 // to break the control signature, hence this approach.
86                 internal virtual void Draw (PaintEventArgs e) 
87                 {
88                         if (redraw) 
89                         {
90                                 Rectangle grid_rect = new Rectangle(0,0,this.Width-1,this.Height-1);
91
92                                 Rectangle grid_left_rect = new Rectangle(grid_rect.Left+1,grid_rect.Top+1,LEFT_COLUMN_WIDTH,ROW_HEIGHT);
93                                 Rectangle grid_label_rect = new Rectangle(grid_left_rect.Right,grid_rect.Top+1,label_column_width,ROW_HEIGHT);
94                                 Rectangle grid_value_rect = new Rectangle(grid_label_rect.Right,grid_rect.Top+1,grid_rect.Right-grid_label_rect.Right,ROW_HEIGHT);
95
96
97                                 Brush label_brush = ThemeEngine.Current.ResPool.GetSolidBrush(ThemeEngine.Current.ColorWindowText);
98                                 Brush label_backcolor_brush = ThemeEngine.Current.ResPool.GetSolidBrush(ThemeEngine.Current.ColorWindow);
99                                 Brush back_color_brush = ThemeEngine.Current.ResPool.GetSolidBrush(this.BackColor);
100                                 Brush control_brush = ThemeEngine.Current.ResPool.GetSolidBrush(property_grid.LineColor);
101                                 Pen control_pen = ThemeEngine.Current.ResPool.GetPen(property_grid.LineColor);
102                                 
103                                 // draw grid outline
104                                 e.Graphics.FillRectangle(back_color_brush,grid_rect);
105                                 e.Graphics.DrawRectangle(ThemeEngine.Current.ResPool.GetPen(SystemColors.ControlDark),grid_rect);
106
107                                 // draw items
108                                 GridItemCollection grid_items = this.property_grid.grid_items;
109                                 for (int i = 0; i < grid_items.Count; i++) {
110                                         GridItem grid_item = grid_items[i];
111                                         
112                                         label_brush = ThemeEngine.Current.ResPool.GetSolidBrush(ThemeEngine.Current.ColorWindowText);
113                                         label_backcolor_brush = ThemeEngine.Current.ResPool.GetSolidBrush(ThemeEngine.Current.ColorWindow);
114                                         if (grid_item == this.property_grid.SelectedGridItem) {
115                                                 label_backcolor_brush = ThemeEngine.Current.ResPool.GetSolidBrush(ThemeEngine.Current.ColorHilight);
116                                                 label_brush = ThemeEngine.Current.ResPool.GetSolidBrush(ThemeEngine.Current.ColorHilightText);
117                                                 grid_textbox.Size = new Size(grid_value_rect.Size.Width-6,grid_value_rect.Size.Height);
118                                                 grid_textbox.Location = new Point(grid_value_rect.Location.X+4,grid_value_rect.Location.Y+1);
119                                                 
120                                                 // PDB - added check to prevent crash with test app
121                                                 if (grid_item.Value != null)  {
122                                                         grid_textbox.Text = grid_item.Value.ToString();
123                                                 } else {
124                                                         grid_textbox.Text = string.Empty;
125                                                 }
126                                         }
127
128                                         e.Graphics.FillRectangle(control_brush,grid_left_rect);
129
130                                         e.Graphics.FillRectangle(label_backcolor_brush,grid_label_rect);
131                                         e.Graphics.DrawRectangle(control_pen,grid_label_rect);
132                                         e.Graphics.DrawString(grid_item.Label,this.Font,label_brush,grid_label_rect.Left + 5,grid_label_rect.Top+1);
133
134                                         e.Graphics.FillRectangle(back_color_brush,grid_value_rect);
135                                         e.Graphics.DrawRectangle(control_pen,grid_value_rect);
136                                         // PDB - added check to prevent crash with test app
137                                         if (grid_item.Value != null) {
138                                                 e.Graphics.DrawString(grid_item.Value.ToString(),new Font(this.Font,FontStyle.Bold),ThemeEngine.Current.ResPool.GetSolidBrush(ThemeEngine.Current.ColorWindowText),grid_value_rect.Left + 2,grid_value_rect.Top+1);
139                                         }
140
141                                    
142                                         // shift down for next item
143                                         grid_left_rect.Y = grid_label_rect.Y = grid_value_rect.Y = grid_left_rect.Y + ROW_HEIGHT;
144                                 }
145                                 redraw = false;
146                         }
147                 }
148
149                         
150                 private void grid_textbox_Validated(object sender, EventArgs e)
151                 {
152                         if (this.property_grid.SelectedGridItem != null)
153                         this.property_grid.SelectedGridItem.PropertyDescriptor.SetValue(this.property_grid.SelectedObject,this.property_grid.SelectedGridItem.PropertyDescriptor.Converter.ConvertTo(((TextBox)sender).Text,this.property_grid.SelectedGridItem.PropertyDescriptor.PropertyType));
154                 }
155
156                 protected override void OnMouseMove(MouseEventArgs e)
157                 {
158                         if (resizing_grid) {
159                                 label_column_width = Math.Max(e.X - LEFT_COLUMN_WIDTH,LEFT_COLUMN_WIDTH);
160                                 Redraw();
161                         } else if (e.X > label_column_width+LEFT_COLUMN_WIDTH - RESIZE_WIDTH && e.X < label_column_width+LEFT_COLUMN_WIDTH + RESIZE_WIDTH) {
162                                 this.Cursor = Cursors.VSplit;
163                         }
164                         base.OnMouseMove (e);
165                 }
166
167
168                 protected override void OnMouseDown(MouseEventArgs e)
169                 {
170                         if (e.X > label_column_width+LEFT_COLUMN_WIDTH + 2 - RESIZE_WIDTH && e.X < label_column_width+LEFT_COLUMN_WIDTH + 2 + RESIZE_WIDTH) {
171                                 resizing_grid = true;
172                         } else {
173                                 int index = e.Y / ROW_HEIGHT;
174                                 if (index < property_grid.grid_items.Count)
175                                         this.property_grid.SelectedGridItem = this.property_grid.grid_items[index];
176                                 base.OnMouseDown (e);
177                         }
178                 }
179
180                 protected override void OnMouseUp(MouseEventArgs e)
181                 {
182                         resizing_grid = false;
183                         base.OnMouseUp (e);
184                 }
185
186
187                 protected override void OnKeyDown(KeyEventArgs e)
188                 {
189                         if (this.property_grid.SelectedGridItem != null) {
190                                 grid_textbox.Focus();
191                         }
192                         base.OnKeyDown (e);
193                 }
194
195
196                 internal void Redraw() 
197                 {
198                         redraw = true;
199                         Refresh ();
200                 }
201
202                 private void RedrawEvent(object sender, System.EventArgs e) 
203                 {
204                         Redraw();
205                 }
206
207                 private void PropertyGridView_MouseMove(object sender, MouseEventArgs e)
208                 {
209
210                         if (e.X > label_column_width+LEFT_COLUMN_WIDTH - RESIZE_WIDTH && e.X < label_column_width+LEFT_COLUMN_WIDTH + RESIZE_WIDTH
211                                 || resizing_grid) {
212                                 this.Cursor = Cursors.VSplit;
213                         } else {
214                                 this.Cursor = Cursors.Default;
215                         }
216                 }
217         }
218 }