?? tabgroupsequence.cs
字號:
// *****************************************************************************
//
// (c) Crownwood Consulting Limited 2002
// All rights reserved. The software and associated documentation
// supplied hereunder are the proprietary information of Crownwood Consulting
// Limited, Haxey, North Lincolnshire, England and are supplied subject to
// licence terms.
//
// Magic Version 1.7 www.dotnetmagic.com
// *****************************************************************************
using System;
using System.IO;
using System.Xml;
using System.Drawing;
using System.Windows.Forms;
using Crownwood.Magic.Common;
using Crownwood.Magic.Controls;
using Crownwood.Magic.Collections;
namespace Crownwood.Magic.Controls
{
public class TabGroupSequence : TabGroupBase, IResizeSource
{
// Class fields
protected const int SPACE_PRECISION = 3;
// Instance fields
protected Control _control;
protected Direction _direction;
protected TabGroupBaseCollection _children;
public TabGroupSequence(TabbedGroups tabbedGroups)
: base(tabbedGroups)
{
// Root instance always defaults to being horizontal
InternalConstruct(tabbedGroups, Direction.Horizontal);
}
public TabGroupSequence(TabbedGroups tabbedGroups, TabGroupBase parent)
: base(tabbedGroups, parent)
{
InternalConstruct(null, Direction.Horizontal);
}
public TabGroupSequence(TabbedGroups tabbedGroups, TabGroupBase parent, Direction direction)
: base(tabbedGroups, parent)
{
InternalConstruct(null, direction);
}
protected void InternalConstruct(Control control, Direction direction)
{
// Do we need to create our own window?
if (control == null)
{
// Yes, use a simple panel for organizing children onto
_control = new Panel();
}
else
{
// No, use the constructor provided one
_control = control;
}
// Hook into control events
_control.Resize += new EventHandler(OnControlResize);
// Assign initial values
_direction = direction;
// Create collection to remember our child objects
_children = new TabGroupBaseCollection();
}
public override int Count
{
get { return _children.Count; }
}
public override bool IsLeaf
{
get { return false; }
}
public override bool IsSequence
{
get { return true; }
}
public override Control GroupControl
{
get { return _control; }
}
public Direction Direction
{
get { return _direction; }
set
{
if (_direction != value)
{
_direction = value;
RepositionChildren();
}
}
}
public VisualStyle Style { get { return _tabbedGroups.Style; } }
public int ResizeBarVector { get { return _tabbedGroups.ResizeBarVector; } }
public Color ResizeBarColor { get { return _tabbedGroups.ResizeBarColor; } }
public Color BackgroundColor { get { return _tabbedGroups.BackColor; } }
public TabGroupLeaf AddNewLeaf()
{
// Create a new leaf instance with correct back references
TabGroupLeaf tgl = new TabGroupLeaf(_tabbedGroups, this);
// Add into the collection
Add(tgl);
// Return its position in collection
return tgl;
}
public TabGroupLeaf InsertNewLeaf(int index)
{
// Range check index
if (index < 0)
throw new ArgumentOutOfRangeException("index", index, "Insert index must be at least 0");
if (index >= _children.Count)
throw new ArgumentOutOfRangeException("index", index, "Cannot insert after end of current entries");
// Create a new leaf instance with correct back references
TabGroupLeaf tgl = new TabGroupLeaf(_tabbedGroups, this);
// Insert into correct collection position
Insert(index, tgl);
// Return its position in collection
return tgl;
}
public void Remove(TabGroupBase group)
{
// Convert from reference to index to use existing RemoveAt implementation
RemoveAt(_children.IndexOf(group));
}
public void RemoveAt(int index)
{
// Range check index
if (index < 0)
throw new ArgumentOutOfRangeException("index", index, "RemoveAt index must be at least 0");
if (index >= _children.Count)
throw new ArgumentOutOfRangeException("index", index, "Cannot remove entry after end of list");
// Is the removed item the active leaf?
if (_children[index] == _tabbedGroups.ActiveLeaf)
{
// Then request movement of the active leaf
_tabbedGroups.MoveActiveToNearestFromLeaf(_children[index]);
}
// Inform control that a group is removed, so it can track number of leafs
_tabbedGroups.GroupRemoved(_children[index]);
// Is this the only Window entry?
if (_children.Count == 1)
{
// Remove Window from appearance
// Use helper method to circumvent form Close bug
ControlHelper.RemoveAt(_control.Controls, 0);
}
else
{
int pos = 0;
// Calculate position of Window to remove
if (index != 0)
pos = index * 2 - 1;
// Remove Window and bar
// Use helper method to circumvent form Close bug
ControlHelper.RemoveAt(_control.Controls, pos);
ControlHelper.RemoveAt(_control.Controls, pos);
}
// How much space is removed entry taking up?
Decimal space = _children[index].Space;
// Remove child from collection
_children.RemoveAt(index);
// Redistribute space to other groups
RemoveWindowSpace(space);
// Update child layout to reflect new proportional spacing values
RepositionChildren();
// Last page removed?
if (_children.Count == 0)
{
// All pages removed, do we need to compact?
if (_tabbedGroups.AutoCompact)
_tabbedGroups.Compact();
}
// Give control chance to enfore leaf policy
_tabbedGroups.EnforceAtLeastOneLeaf();
// Mark layout as dirty
if (_tabbedGroups.AutoCalculateDirty)
_tabbedGroups.Dirty = true;
}
public int IndexOf(TabGroupBase group)
{
return _children.IndexOf(group);
}
public void Clear()
{
// Do we contain the active leaf?
if (_children.IndexOf(_tabbedGroups.ActiveLeaf) != 0)
{
// Then request movement of the active leaf to different group
_tabbedGroups.MoveActiveToNearestFromSequence(this);
}
// Remove all child controls
ControlHelper.RemoveAll(_control);
// Remove all child group references
_children.Clear();
_control.Invalidate();
// All pages removed, do we need to compact?
if (_tabbedGroups.AutoCompact)
_tabbedGroups.Compact();
// Mark layout as dirty
if (_tabbedGroups.AutoCalculateDirty)
_tabbedGroups.Dirty = true;
}
public TabGroupBase this[int index]
{
get { return _children[index]; }
}
public override void Notify(NotifyCode code)
{
// Handle codes of interest
switch(code)
{
case NotifyCode.ProminentChanged:
case NotifyCode.MinimumSizeChanged:
// Must reposition to take account of change
RepositionChildren();
break;
case NotifyCode.StyleChanged:
// Inform each resize bar of change in style
foreach(Control c in _control.Controls)
if (c is ResizeBar)
(c as ResizeBar).Style = _tabbedGroups.Style;
// Reposition the children based on new resize bar size
RepositionChildren();
break;
case NotifyCode.ResizeBarVectorChanged:
// Recalculate layout of childreen
RepositionChildren();
break;
case NotifyCode.ResizeBarColorChanged:
// If we are showing at least one resize bar
if (_children.Count > 1)
{
// Then must repaint in new color
_control.Invalidate();
}
break;
}
// Pass notification to children
foreach(TabGroupBase child in _children)
child.Notify(code);
}
public void Rebalance(bool recurse)
{
if (_children.Count > 0)
{
// Calculate how much space to give each child
Decimal newSpace = Decimal.Round(100m / _children.Count, SPACE_PRECISION);
// Assign equal space to all entries
foreach(TabGroupBase group in _children)
group.Space = newSpace;
Decimal totalSpace = 100m - (newSpace * _children.Count);
// Allocate rounding errors to last child
if (totalSpace != 0)
_children[_children.Count - 1].Space += 100m - totalSpace;
// Propogate effect into child sequences?
if (recurse)
{
foreach(TabGroupBase group in _children)
if (group.IsSequence)
(group as TabGroupSequence).Rebalance(recurse);
}
}
// Update child layout to reflect new proportional spacing values
RepositionChildren();
}
public override bool ContainsProminent(bool recurse)
{
// Cache the currently selected prominent group
TabGroupLeaf prominent = _tabbedGroups.ProminentLeaf;
// If not defined then we cannot contain it!
if (prominent == null)
return false;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -