📄 zonesequence.cs
字号:
{
Content c = child as Content;
// We currently only understand Windows that have Content as children
if (c != null)
{
StringCollection best;
StringCollection next;
StringCollection previous;
GetWindowContentFriends(w, out best, out next, out previous);
// Create a restore object that will find the correct WindowContent to
// place a Content in within a specified Zone, or it will create a new
// WindowContent in an appropriate relative ordering
Restore zoneRestore = new RestoreZoneAffinity(childRestore, c, best, next, previous);
if (_state == State.Floating)
{
// Create a restore object to find the correct Floating Form to restore inside
// or it will create a new Floating Form as appropriate
return new RestoreContentFloatingAffinity(zoneRestore, _state, c, best, ZoneHelper.ContentNames(this));
}
else
{
StringCollection zoneBest;
StringCollection zoneNext;
StringCollection zonePrevious;
StringCollection zoneNextAll;
StringCollection zonePreviousAll;
GetZoneContentFriends(c, out zoneBest, out zoneNext, out zonePrevious,
out zoneNextAll, out zonePreviousAll);
// Create a restore object able to find the correct Zone in the appropriate
// docking direction and then restore into that Zone. If no appropriate Zone
// found then create a new one
return new RestoreContentDockingAffinity(zoneRestore, _state, c, zoneBest,
zoneNext, zonePrevious,
zoneNextAll, zonePreviousAll);
}
}
return null;
}
public override void PropogateNameValue(PropogateName name, object value)
{
base.PropogateNameValue(name, value);
// Reduce flicker during update
SuspendLayout();
if (name == PropogateName.ZoneMinMax)
{
if (_zoneMinMax != (bool)value)
{
// Remember the new value
_zoneMinMax = (bool)value;
// If turning off the min/max ability
if (!_zoneMinMax)
_maximizedWindow = null; // no window can be currently maximized
// Get child windows to retest the maximize capability
OnRefreshMaximize(EventArgs.Empty);
}
}
// Update each resize bar control
foreach(Control c in this.Controls)
{
ResizeBar rb = c as ResizeBar;
if (rb != null)
rb.PropogateNameValue(name, value);
}
// Recalculate positions using new values
RepositionControls();
ResumeLayout();
}
protected void GetZoneContentFriends(Content c,
out StringCollection zoneBest,
out StringCollection zoneNext,
out StringCollection zonePrevious,
out StringCollection zoneNextAll,
out StringCollection zonePreviousAll)
{
// Out best friends are all those Content inside this Zone but with the ones
// in the same Window as the first in list and so the highest priority
zoneBest = ZoneHelper.ContentNamesInPriority(this,c);
zoneNext = new StringCollection();
zonePrevious = new StringCollection();
zoneNextAll = new StringCollection();
zonePreviousAll = new StringCollection();
bool before = true;
foreach(Control control in _manager.Container.Controls)
{
Zone z = control as Zone;
if (z != null)
{
if (z == this)
before = false;
else
{
ContentCollection newContent = ZoneHelper.Contents(z);
foreach(Content content in newContent)
{
if (before)
{
if (z.State == this.State)
zonePrevious.Add(content.Title);
zonePreviousAll.Add(content.Title);
}
else
{
if (z.State == this.State)
zoneNext.Add(content.Title);
zoneNextAll.Add(content.Title);
}
}
newContent.Clear();
}
}
}
}
protected void GetWindowContentFriends(Window match,
out StringCollection best,
out StringCollection next,
out StringCollection previous)
{
best = new StringCollection();
next = new StringCollection();
previous = new StringCollection();
bool before = true;
foreach(Window w in _windows)
{
WindowContent wc = w as WindowContent;
// Is this the Window we are searching for?
if (w == match)
{
if (wc != null)
{
// Best friends are those in the matching Window
foreach(Content content in wc.Contents)
best.Add(content.Title);
}
before = false;
}
else
{
if (wc != null)
{
// Remember all found Content in appropriate next/previous collection
foreach(Content content in wc.Contents)
{
if (before)
previous.Add(content.Title);
else
next.Add(content.Title);
}
}
}
}
}
public void AddHotZones(Redocker redock, HotZoneCollection collection)
{
RedockerContent redocker = redock as RedockerContent;
// Allow all the Window objects a chance to add HotZones
foreach(Window w in _windows)
{
IHotZoneSource ag = w as IHotZoneSource;
// Does this control expose an interface for its own HotZones?
if (ag != null)
ag.AddHotZones(redock, collection);
}
// Check for situations that need extra attention...
//
// (1) Do not allow a WindowContent from a ZoneSequence to be redocked into the
// same ZoneSequence. As removing it will cause the Zone to be destroyed and
// so it cannot be added back again. Is not logical anyway.
//
// (2) If the source is in this ZoneSequence we might need to adjust the insertion
// index because the item being removed will reduce the count for when the insert
// takes place.
bool indexAdjustTest = false;
WindowContent redockWC = redocker.WindowContent;
if (_windows.Count == 1)
{
if (redockWC != null)
if (redockWC == _windows[0])
if ((redocker.Content == null) || (redockWC.Contents.Count == 1))
return;
}
else
{
if (_windows.Contains(redockWC))
{
if ((redocker.Content == null) || (redockWC.Contents.Count == 1))
indexAdjustTest = true;
}
}
// Find the Zone client area in screen coordinates
Rectangle zoneArea = this.RectangleToScreen(this.ClientRectangle);
int length;
// Give a rough idea of the new window size
if (_direction == Direction.Vertical)
length = zoneArea.Height / (_windows.Count + 1);
else
length = zoneArea.Width / (_windows.Count + 1);
AddHotZoneWithIndex(collection, zoneArea, length, 0);
int addative = 0;
int count = _windows.Count;
for(int index=1; index<count; index++)
{
// Grab the Window for this index
WindowContent wc = _windows[index] as WindowContent;
if (indexAdjustTest)
{
if (wc == redockWC)
--addative;
}
AddHotZoneWithIndex(collection,
wc.RectangleToScreen(wc.ClientRectangle),
length,
index + addative);
}
if (_windows.Count > 0)
{
// Find hot area and new size for last docking position
Rectangle lastArea = zoneArea;
Rectangle lastSize = zoneArea;
if (_direction == Direction.Vertical)
{
lastArea.Y = lastArea.Bottom - _hotVectorBeforeControl;
lastArea.Height = _hotVectorBeforeControl;
lastSize.Y = lastSize.Bottom - length;
lastSize.Height = length;
}
else
{
lastArea.X = lastArea.Right - _hotVectorBeforeControl;
lastArea.Width = _hotVectorBeforeControl;
lastSize.X = lastSize.Right - length;
lastSize.Width = length;
}
collection.Add(new HotZoneSequence(lastArea, lastSize, this, _windows.Count + addative));
}
}
public void ModifyWindowSpace(Window w, Decimal newSpace)
{
// Double check this Window is a member of the collection
if (_windows.Contains(w))
{
// Cannot reallocate space if it is the only element
if (_windows.Count > 1)
{
int otherWindows = _windows.Count - 1;
// Limit the resize allowed
if (newSpace > 100m)
newSpace = 100m;
if (newSpace <= 0m)
newSpace = 0m;
if (newSpace != w.ZoneArea)
{
// How much needs to be reallocated to other windows
Decimal diff = w.ZoneArea - newSpace;
// Reducing the amount of space?
if (diff > 0m)
{
// How much to give each of the other windows
Decimal extra = diff / otherWindows;
// Looping counters
Decimal allocated = 0m;
int found = 0;
foreach(Window target in _windows)
{
// We only process the other windows
if (target != w)
{
// Allocate it extra space
target.ZoneArea += extra;
// Keep count of total extra allocated
allocated += extra;
// Count number of others processed
found++;
// The last window to be allocated needs to also be given any rouding
// errors that occur from previous division, to ensure that the total
// space it always exactly equal to 100.
if (found == otherWindows)
target.ZoneArea += (diff - allocated);
}
}
}
else
{
// Easier to work with positive than negative numbers
diff = -diff;
while(diff > 0m)
{
// How much to grab from each of the other windows
Decimal extra = diff / otherWindows;
foreach(Window target in _windows)
{
// We only process the other windows
if (target != w)
{
if (target.ZoneArea > 0m)
{
if (target.ZoneArea < extra)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -