//Except where stated all code and programs in this project are the copyright of Jim Blackler, 2008.
//jimblackler@gmail.com
//
//This is free software. Libraries and programs are distributed under the terms of the GNU Lesser
//General Public License. Please see the files COPYING and COPYING.LESSER.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Windows.Forms;
namespace MiscControls
{
///
/// A control that sizes all sub-controls on a parent form proportionally
///
public partial class FormScaler : Component
{
///
/// Record of the parent form
///
[Browsable(false)]
[DefaultValue("")]
public Control ParentControl
{
get
{
// Designer code ... set the form
if ((parentControl == null) && DesignMode)
{
IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));
if (host != null)
{
parentControl = host.RootComponent as Control;
}
}
return parentControl;
}
set
{
if (parentControl != value)
{
// Quite a bit of setup is done as soon as we know the parent form
parentControl = value;
parentControl.FindForm().Load += new EventHandler(FormScaler_Load);
parentControl.Resize += new EventHandler(parentControl_Resize);
}
}
}
///
/// Called to record the positions of the controls after the client window is initialised
///
void FormScaler_Load(object sender, EventArgs e)
{
originalWidth = parentControl.ClientRectangle.Width;
originalHeight = parentControl.ClientRectangle.Height;
// record the original positions of the controls
originalSizesAndPositions = new List();
Control.ControlCollection collection = parentControl.Controls;
RecordControlCollection(collection);
}
private void RecordControlCollection(Control.ControlCollection collection)
{
foreach (Control control in collection)
{
if (control as MenuStrip == null)
{
OriginalSizeAndPosition originalSizeAndPosition = new OriginalSizeAndPosition();
originalSizeAndPosition.originalWidth = control.Size.Width;
originalSizeAndPosition.originalHeight = control.Size.Height;
originalSizeAndPosition.originalX = control.Location.X;
originalSizeAndPosition.originalY = control.Location.Y;
originalSizeAndPosition.originalFontSize = control.Font.Size;
originalSizeAndPosition.control = control;
originalSizesAndPositions.Add(originalSizeAndPosition);
RecordControlCollection(control.Controls);
}
}
}
///
/// Size the parent control proportionally
///
void parentControl_Resize(object sender, EventArgs e)
{
if (originalSizesAndPositions == null)
{
return;
}
else
{
if (previousWidth != parentControl.ClientRectangle.Width || previousHeight != parentControl.ClientRectangle.Height)
{
int currentWidth = parentControl.ClientRectangle.Width;
int currentHeight = parentControl.ClientRectangle.Height;
if (currentWidth > 0 && currentHeight > 0)
{
int topOffset;
Form clientForm = parentControl as Form;
if (clientForm == null)
{
topOffset = 0;
}
else
{
topOffset = clientForm.MainMenuStrip.Height;
}
float propX = (float)currentWidth / originalWidth;
float propY = (float)(currentHeight - topOffset) / (originalHeight - topOffset);
parentControl.SuspendLayout();
foreach (OriginalSizeAndPosition originalSizeAndPosition in originalSizesAndPositions)
{
originalSizeAndPosition.control.SetBounds((int)(propX * originalSizeAndPosition.originalX),
(int)(topOffset + propY * (originalSizeAndPosition.originalY - topOffset)),
(int)(propX * originalSizeAndPosition.originalWidth),
(int)(propY * originalSizeAndPosition.originalHeight));
originalSizeAndPosition.control.Font =
new Font(originalSizeAndPosition.control.Font.FontFamily,
Math.Min(propX, propY) * originalSizeAndPosition.originalFontSize,
originalSizeAndPosition.control.Font.Unit);
}
parentControl.ResumeLayout();
}
previousWidth = currentWidth;
previousHeight = currentHeight;
}
return;
}
}
// Fields follow
private Control parentControl;
private List originalSizesAndPositions;
private int originalWidth;
private int originalHeight;
private int previousWidth;
private int previousHeight;
///
/// A record of the original bounds stored for each child control
///
class OriginalSizeAndPosition
{
public int originalWidth;
public int originalHeight;
public int originalX;
public int originalY;
public float originalFontSize;
public Control control;
}
}
}