| Wheelchair Control Diploma Thesis, Author: Ondrej Vozda, FEEC BUT, 2013

- Main Page
- Packages
- Classes
- Files

- File List

All Classes Namespaces Functions Variables Enumerations Enumerator Properties Events Pages
CollapsibleGroupbox.cs
1 ﻿using System;
2 using System.ComponentModel;
3 using System.Drawing;
4 using System.Drawing.Drawing2D;
5 using System.Windows.Forms;
6 using System.Drawing.Extended;
7
8 namespace WheelchairControl
9 {
21 [ToolboxBitmap(typeof(CollapsibleGroupBox))]
22 public class CollapsibleGroupBox : GroupBox
23 {
24 #region Fields
25
26 private Color m_borderColor = Color.FromArgb(208, 208, 191);
27 private Color m_textColor = Color.Black;
28 private Rectangle m_toggleRect = new Rectangle(8, 2, 11, 11);
29 private bool m_collapsed = false;
30 private bool m_bResizingFromCollapse = false;
31
32 private const int m_collapsedHeight = 20;
33 private Size m_FullSize = Size.Empty;
34 private System.ComponentModel.Container components = null;
35
36 #endregion
37
38 #region Events & Delegates
39
43 public delegate void CollapseBoxClickedEventHandler(object sender);
44
48 public event CollapseBoxClickedEventHandler CollapseBoxClickedEvent;
49
50 #endregion
51
52 #region Construct & Dispose
53
57 public CollapsibleGroupBox()
58 {
59 // This call is required by the Windows.Forms Form Designer.
60 InitializeComponent();
61 }
62
66 protected override void Dispose(bool disposing)
67 {
68 if (disposing)
69 {
70 if (components != null)
71 {
72 components.Dispose();
73 }
74 }
75 base.Dispose(disposing);
76 }
77
78 #endregion
79
80 #region Component Designer generated code
81
82
83
84
85 private void InitializeComponent()
86 {
87 components = new System.ComponentModel.Container();
88 }
89 #endregion
90
91 #region Public Properties
92
96 [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
97 public int FullHeight
98 {
99 get { return m_FullSize.Height; }
100 }
101
105 [DefaultValue(false), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
106 [Description("Determines if object is initially collapsed.")]
107 public bool IsCollapsed
108 {
109 get { return m_collapsed; }
110 set
111 {
112 if (value != m_collapsed)
113 {
114 m_collapsed = value;
115
116 if (!value)
117 // Expand
118 this.Size = m_FullSize;
119 else
120 {
121 // Collapse
122 m_bResizingFromCollapse = true;
123 this.Height = m_collapsedHeight;
124 m_bResizingFromCollapse = false;
125 }
126
127 foreach (Control c in Controls)
128 c.Visible = !value;
129
130 Invalidate();
131 }
132 }
133 }
134
138 [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
139 public int CollapsedHeight
140 {
141 get { return m_collapsedHeight; }
142 }
143
144 #endregion
145
146 #region Private Properties
147
148 Image MinusImage
149 {
150 get { return WheelchairControl.Properties.Resources.minus; }
151 }
152
153 Image PlusImage
154 {
155 get { return WheelchairControl.Properties.Resources.plus; }
156 }
157
158 #endregion
159
160 #region Overrides
161
166 protected override void OnMouseUp(MouseEventArgs e)
167 {
168 if (m_toggleRect.Contains(new Point(e.X, e.Y)))
169 ToggleCollapsed();
170 else
171 base.OnMouseUp(e);
172 }
173
178 protected override void OnPaint(PaintEventArgs e)
179 {
180 HandleResize();
181 //base.OnPaint(e);
182 DrawGroupBox(e.Graphics);
183 DrawToggleButton(e.Graphics);
184 }
185
186 #endregion
187
188 #region Implimentation
189
190 void DrawGroupBox(Graphics g)
191 {
192 // Get windows to draw the GroupBox
193 Rectangle bounds = new Rectangle(ClientRectangle.X, ClientRectangle.Y + 6, ClientRectangle.Width, ClientRectangle.Height - 6);
194
195 // Text Formating positioning & Size
196 StringFormat sf = new StringFormat();
197 int i_textPos = (bounds.X + 8) + m_toggleRect.Width + 2;
198 int i_textSize = (int)g.MeasureString(Text, this.Font).Width;
199 i_textSize = i_textSize < 1 ? 1 : i_textSize;
200 int i_endPos = i_textPos + i_textSize + 1;
201
202 // Draw the Border
203 ExtendedGraphics eg = new ExtendedGraphics(g);
204 using (Pen p = new Pen(m_borderColor))
205 eg.DrawRoundRectangle(p, 0, 6, Width - 1, Height - 7, 5F);
206
207 // Draw a line to cover the GroupBox border where the text will sit
208 g.FillRectangle(SystemBrushes.Control, 8, 2, i_endPos - 8, 12);
209
210 // Draw the GroupBox text
211 using (SolidBrush drawBrush = new SolidBrush(m_textColor))
212 g.DrawString(Text, this.Font, drawBrush, i_textPos, 0);
213 }
214
215 void DrawToggleButton(Graphics g)
216 {
217 if (IsCollapsed)
218 g.DrawImage(PlusImage, m_toggleRect);
219 else
220 g.DrawImage(MinusImage, m_toggleRect);
221 }
222
223 void ToggleCollapsed()
224 {
225 IsCollapsed = !IsCollapsed;
226
227 if (CollapseBoxClickedEvent != null)
228 CollapseBoxClickedEvent(this);
229 }
230
231 void HandleResize()
232 {
233 if (!m_bResizingFromCollapse && !m_collapsed)
234 m_FullSize = this.Size;
235 }
236
237 #endregion
238 }
239 }
240
241 // A simple extension to the Graphics class for extended
242 // graphic routines, such,
243 // as for creating rounded rectangles.
244 // Because, Graphics class is an abstract class,
245 // that is why it can not be inherited. Although,
246 // I have provided a simple constructor
247 // that builds the ExtendedGraphics object around a
248 // previously created Graphics object.
249 // Author: Aaron Reginald <aaronreginald@yahoo.com>
250 // URL: http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=12835
251 namespace System.Drawing.Extended
252 {
253
258 public class ExtendedGraphics
259 {
260
261 private Graphics mGraphics;
262
266 public Graphics Graphics
267 {
268 get { return this.mGraphics; }
269 set { this.mGraphics = value; }
270 }
271
276 public ExtendedGraphics(Graphics graphics)
277 {
278 this.Graphics = graphics;
279 }
280
281
282 #region Fills a Rounded Rectangle with integers.
283
293 public void FillRoundRectangle(System.Drawing.Brush brush,
294 int x, int y,
295 int width, int height, int radius)
296 {
297
298 float fx = Convert.ToSingle(x);
299 float fy = Convert.ToSingle(y);
300 float fwidth = Convert.ToSingle(width);
301 float fheight = Convert.ToSingle(height);
302 float fradius = Convert.ToSingle(radius);
303 this.FillRoundRectangle(brush, fx, fy,
304 fwidth, fheight, fradius);
305
306 }
307 #endregion
308
309 #region Fills a Rounded Rectangle with continuous numbers.
310
320 public void FillRoundRectangle(System.Drawing.Brush brush,
321 float x, float y,
322 float width, float height, float radius)
323 {
324 RectangleF rectangle = new RectangleF(x, y, width, height);
325 GraphicsPath path = this.GetRoundedRect(rectangle, radius);
326 this.Graphics.FillPath(brush, path);
327 }
328 #endregion
329
330 #region Draws a Rounded Rectangle border with integers.
331
341 public void DrawRoundRectangle(System.Drawing.Pen pen, int x, int y,
342 int width, int height, int radius)
343 {
344 float fx = Convert.ToSingle(x);
345 float fy = Convert.ToSingle(y);
346 float fwidth = Convert.ToSingle(width);
347 float fheight = Convert.ToSingle(height);
348 float fradius = Convert.ToSingle(radius);
349 this.DrawRoundRectangle(pen, fx, fy, fwidth, fheight, fradius);
350 }
351 #endregion
352
353 #region Draws a Rounded Rectangle border with continuous numbers.
354
364 public void DrawRoundRectangle(System.Drawing.Pen pen,
365 float x, float y,
366 float width, float height, float radius)
367 {
368 RectangleF rectangle = new RectangleF(x, y, width, height);
369 GraphicsPath path = this.GetRoundedRect(rectangle, radius);
370 this.Graphics.DrawPath(pen, path);
371 }
372 #endregion
373
374 #region Get the desired Rounded Rectangle path.
375 private GraphicsPath GetRoundedRect(RectangleF baseRect,
376 float radius)
377 {
378 // if corner radius is less than or equal to zero,
379 // return the original rectangle
380 if (radius <= 0.0F)
381 {
382 GraphicsPath mPath = new GraphicsPath();
383 mPath.AddRectangle(baseRect);
384 mPath.CloseFigure();
385 return mPath;
386 }
387
388 // if the corner radius is greater than or equal to
389 // half the width, or height (whichever is shorter)
390 // then return a capsule instead of a lozenge
391 if (radius >= (Math.Min(baseRect.Width, baseRect.Height)) / 2.0)
392 return GetCapsule(baseRect);
393
394 // create the arc for the rectangle sides and declare
395 // a graphics path object for the drawing
396 float diameter = radius * 2.0F;
397 SizeF sizeF = new SizeF(diameter, diameter);
398 RectangleF arc = new RectangleF(baseRect.Location, sizeF);
399 GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
400
401 // top left arc
402 path.AddArc(arc, 180, 90);
403
404 // top right arc
405 arc.X = baseRect.Right - diameter;
406 path.AddArc(arc, 270, 90);
407
408 // bottom right arc
409 arc.Y = baseRect.Bottom - diameter;
410 path.AddArc(arc, 0, 90);
411
412 // bottom left arc
413 arc.X = baseRect.Left;
414 path.AddArc(arc, 90, 90);
415
416 path.CloseFigure();
417 return path;
418 }
419 #endregion
420
421 #region Gets the desired Capsular path.
422 private GraphicsPath GetCapsule(RectangleF baseRect)
423 {
424 float diameter;
425 RectangleF arc;
426 GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
427 try
428 {
429 if (baseRect.Width > baseRect.Height)
430 {
431 // return horizontal capsule
432 diameter = baseRect.Height;
433 SizeF sizeF = new SizeF(diameter, diameter);
434 arc = new RectangleF(baseRect.Location, sizeF);
435 path.AddArc(arc, 90, 180);
436 arc.X = baseRect.Right - diameter;
437 path.AddArc(arc, 270, 180);
438 }
439 else if (baseRect.Width < baseRect.Height)
440 {
441 // return vertical capsule
442 diameter = baseRect.Width;
443 SizeF sizeF = new SizeF(diameter, diameter);
444 arc = new RectangleF(baseRect.Location, sizeF);
445 path.AddArc(arc, 180, 180);
446 arc.Y = baseRect.Bottom - diameter;
447 path.AddArc(arc, 0, 180);
448 }
449 else
450 {
451 // return circle
452 path.AddEllipse(baseRect);
453 }
454 }
455 catch (Exception)
456 {
457 path.AddEllipse(baseRect);
458 }
459 finally
460 {
461 path.CloseFigure();
462 }
463 return path;
464 }
465 #endregion
466 }
467 }