//-----------------------------------------------------------------------
//
// Copyright © 2012 Nils Hammar. All rights reserved.
//
//-----------------------------------------------------------------------
/*
* Software to access vehicle information via the OBD-II connector.
*
* Copyright © 2012 Nils Hammar
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Alternative licensing is possible, see the licensing document.
*
* The above text may not be removed or modified.
*/
namespace Gauges.TelltalePanel
{
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
///
/// Layout engine that works best for equally sized object which shall be displayed around the center of a panel.
///
public class CenterLayout : System.Windows.Forms.Layout.LayoutEngine
{
///
/// Initializes a new instance of the class.
///
/// Container to layout in.
/// Layout event arguments.
/// Whether or not the container's
/// parent should perform layout as a result of this
/// layout.
public override bool Layout(
object container,
LayoutEventArgs layoutEventArgs)
{
Control parent = container as Control;
// Use DisplayRectangle so that parent.Padding is honored.
Rectangle parentDisplayRectangle = parent.DisplayRectangle;
int displayWidth = parentDisplayRectangle.Width;
int center = parent.Width / 2;
int maxItemWidth = 0;
int maxItemHeight = 0;
foreach (Control c in parent.Controls)
{
int h = c.Height + c.Margin.Top + c.Margin.Bottom;
int w = c.Width + c.Margin.Left + c.Margin.Right;
if (h > maxItemHeight)
{
maxItemHeight = h;
}
if (w > maxItemWidth)
{
maxItemWidth = w;
}
}
if (center < maxItemWidth)
{
center = 0;
}
int leftPos = center - maxItemWidth;
int rightPos = center;
int nextY = 0;
bool incYleft = false;
bool incYright = false;
bool visible = true;
int n = 1;
foreach (Control c in parent.Controls)
{
c.Visible = visible;
// Only apply layout to visible controls.
if (!c.Visible)
{
continue;
}
// Determine location.
Point location;
if ((n % 2) == 0)
{
location = new Point(leftPos, nextY);
leftPos -= maxItemWidth;
if (leftPos < 0)
{
incYleft = true;
}
}
else
{
location = new Point(rightPos, nextY);
rightPos += maxItemWidth;
if (rightPos > displayWidth)
{
incYright = true;
}
}
// Respect the margin of the control:
// shift over the left and the top.
location.Offset(c.Margin.Left, c.Margin.Top);
// Set the location of the control.
c.Location = location;
if (incYleft || incYright || center < maxItemWidth)
{
nextY += maxItemHeight;
leftPos = center - maxItemWidth;
rightPos = center;
incYleft = false;
incYright = false;
if ((nextY + maxItemHeight) > parentDisplayRectangle.Height)
{
visible = false;
}
}
if (center < maxItemWidth)
{
n += 2;
}
else
{
n++;
}
}
// Optional: Return whether or not the container's
// parent should perform layout as a result of this
// layout. Some layout engines return the value of
// the container's AutoSize property.
return false;
}
}
}