📄 axsidebar.cs
字号:
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision: 915 $</version>
// </file>
using System;
using System.Collections;
using System.Drawing;
using System.Windows.Forms;
namespace ICSharpCode.SharpDevelop.Gui
{
public interface ISideTabItemFactory
{
AxSideTabItem CreateSideTabItem(string name);
AxSideTabItem CreateSideTabItem(string name, object tag);
AxSideTabItem CreateSideTabItem(string name, object tag, Bitmap bitmap);
}
public class DefaultSideTabItemFactory : ISideTabItemFactory
{
public AxSideTabItem CreateSideTabItem(string name)
{
return new AxSideTabItem(name);
}
public AxSideTabItem CreateSideTabItem(string name, object tag)
{
return new AxSideTabItem(name, tag);
}
public AxSideTabItem CreateSideTabItem(string name, object tag, Bitmap bitmap)
{
return new AxSideTabItem(name, tag, bitmap);
}
}
public interface ISideTabFactory
{
AxSideTab CreateSideTab(AxSideBar sideBar, string name);
}
public class DefaultSideTabFactory : ISideTabFactory
{
public AxSideTab CreateSideTab(AxSideBar sideBar, string name)
{
return new AxSideTab(sideBar, name);
}
}
public class AxSideBar : UserControl
{
SideTabCollection sideTabs;
AxSideTab activeTab = null;
protected SideTabContent sideTabContent = new SideTabContent();
AxSideTab renameTab = null;
AxSideTabItem renameTabItem = null;
TextBox renameTextBox = new TextBox();
ScrollBar scrollBar = new VScrollBar();
Point mousePosition;
protected bool doAddTab = false;
public bool DoAddTab {
get {
return doAddTab;
}
set {
doAddTab = value;
}
}
ISideTabFactory sideTabFactory = new DefaultSideTabFactory();
ISideTabItemFactory sideTabItemFactory = new DefaultSideTabItemFactory();
public ISideTabItemFactory SideTabItemFactory {
get {
return sideTabItemFactory;
}
set {
sideTabItemFactory = value;
}
}
public ISideTabFactory SideTabFactory {
get {
return sideTabFactory;
}
set {
sideTabFactory = value;
}
}
public SideTabCollection Tabs {
get {
return sideTabs;
}
}
public AxSideTab ActiveTab {
get {
return activeTab;
}
set {
if (activeTab != value) {
if (activeTab != null) {
activeTab.ScrollIndex = scrollBar.Value;
}
activeTab = value;
if (activeTab != null) {
scrollBar.SmallChange = 1;
scrollBar.LargeChange = sideTabContent.Height / activeTab.ItemHeight;
scrollBar.Maximum = activeTab.Items.Count;
scrollBar.Value = activeTab.ScrollIndex;
}
}
Refresh();
}
}
protected override void OnResize(System.EventArgs e)
{
base.OnResize(e);
scrollBar.LargeChange = sideTabContent.Height / activeTab.ItemHeight;
}
public AxSideBar()
{
ResizeRedraw = true;
AllowDrop = true;
sideTabs = new SideTabCollection(this);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.CacheText, true);
// itemTabMenu.Popup += new EventHandler(ItemContextMenuPopup);
renameTextBox.Visible = false;
renameTextBox.BorderStyle = BorderStyle.None;
Controls.Add(renameTextBox);
scrollBar.Scroll += new ScrollEventHandler(ScrollBarScrolled);
Controls.Add(scrollBar);
sideTabContent.SideBar = this;
Controls.Add(sideTabContent);
}
protected void ExitRenameMode()
{
if (renameTab != null) {
renameTextBox.Visible = false;
renameTab = null;
doAddTab = false;
} else if (renameTabItem != null) {
renameTextBox.Visible = false;
renameTabItem = null;
}
}
public void EnsureVisible(AxSideTabItem item)
{
int index = activeTab.Items.IndexOf(item);
if (index != -1) {
if (index < scrollBar.Value) {
scrollBar.Value = Math.Max(scrollBar.Minimum, Math.Min(scrollBar.Maximum, index));
ScrollBarScrolled(null, null);
} else if (index > scrollBar.Value + (sideTabContent.Height - 15) / 20) {
scrollBar.Value = Math.Max(scrollBar.Minimum, Math.Min(scrollBar.Maximum, index - (sideTabContent.Height - 15) / 20));
ScrollBarScrolled(null, null);
}
}
}
protected override bool ProcessCmdKey(ref Message msg,Keys keyData)
{
int index;
if (base.ProcessCmdKey(ref msg, keyData)) {
return true;
}
bool isInRenameMode = renameTab != null || renameTabItem != null;
switch (keyData) {
case Keys.Home:
if (activeTab.Items.Count > 0 && !isInRenameMode) {
activeTab.ChoosedItem = activeTab.Items[0];
EnsureVisible(activeTab.ChoosedItem);
Refresh();
}
break;
case Keys.End:
if (activeTab.Items.Count > 0 && !isInRenameMode) {
activeTab.ChoosedItem = activeTab.Items[activeTab.Items.Count - 1];
EnsureVisible(activeTab.ChoosedItem);
Refresh();
}
break;
case Keys.PageUp:
if (activeTab.Items.Count > 0 && !isInRenameMode) {
index = Math.Max(0, activeTab.Items.IndexOf(activeTab.ChoosedItem) - scrollBar.LargeChange);
activeTab.ChoosedItem = activeTab.Items[index];
EnsureVisible(activeTab.ChoosedItem);
Refresh();
}
break;
case Keys.PageDown:
if (activeTab.Items.Count > 0 && !isInRenameMode) {
index = Math.Min(activeTab.Items.Count - 1, activeTab.Items.IndexOf(activeTab.ChoosedItem) + scrollBar.LargeChange);
activeTab.ChoosedItem = activeTab.Items[index];
EnsureVisible(activeTab.ChoosedItem);
Refresh();
}
break;
case Keys.Down:
if (activeTab.Items.Count > 0 && !isInRenameMode) {
if (activeTab.ChoosedItem != null) {
activeTab.ChoosedItem = activeTab.Items[Math.Min(activeTab.Items.Count - 1, activeTab.Items.IndexOf(activeTab.ChoosedItem) + 1)];
} else {
activeTab.ChoosedItem = activeTab.Items[0];
}
activeTab.SelectedItem = null;
EnsureVisible(activeTab.ChoosedItem);
Refresh();
}
return true;
case Keys.Up:
if (activeTab.Items.Count > 0 && !isInRenameMode) {
if (activeTab.ChoosedItem != null) {
activeTab.ChoosedItem = activeTab.Items[Math.Max(0, activeTab.Items.IndexOf(activeTab.ChoosedItem) - 1)];
} else {
activeTab.ChoosedItem = activeTab.Items[0];
}
activeTab.SelectedItem = null;
EnsureVisible(activeTab.ChoosedItem);
Refresh();
}
return true;
case Keys.Control | Keys.Up:
ActiveTab = Tabs[Math.Max(0, Tabs.IndexOf(ActiveTab) - 1)];
Refresh();
return true;
case Keys.Control | Keys.Down:
ActiveTab = Tabs[Math.Min(Tabs.Count - 1, Tabs.IndexOf(ActiveTab) + 1)];
Refresh();
return true;
case Keys.Return:
if (renameTab != null) {
renameTab.Name = renameTextBox.Text;
ExitRenameMode();
} else if (renameTabItem != null) {
renameTabItem.Name = renameTextBox.Text;
ExitRenameMode();
}
return true;
case Keys.Escape:
if (renameTab != null) {
if (doAddTab) {
Tabs.RemoveAt(Tabs.Count - 1);
renameTab = null;
renameTextBox.Visible = false;
doAddTab = false;
Refresh();
} else {
ExitRenameMode();
}
} else if (renameTabItem != null) {
ExitRenameMode();
}
return true;
}
return false;
}
public void StartRenamingOf(AxSideTabItem item)
{
EnsureVisible(item);
renameTabItem = item;
Point location = activeTab.GetLocation(item);
location.X += Bounds.X + 5 + sideTabContent.Location.X + 16;
location.Y += Bounds.Y + 3 + sideTabContent.Location.Y - scrollBar.Value * 20;
renameTextBox.Location = location;
renameTextBox.Width = Width - 10;
renameTextBox.Height = Font.Height - 2;
renameTextBox.Text = item.Name;
renameTextBox.Visible = true;
renameTextBox.Focus();
}
public void StartRenamingOf(AxSideTab tab)
{
int index = Tabs.IndexOf(tab);
renameTab = Tabs[index];
Point location = GetLocation(renameTab);
location.X += 3;
location.Y += 1;
renameTextBox.Location = location;
renameTextBox.Width = Width - 10;
renameTextBox.Height = Font.Height - 2;
renameTextBox.Text = renameTab.Name;
renameTextBox.Visible = true;
renameTextBox.Focus();
}
void ItemContextMenuPopup(object sender, EventArgs e)
{
activeTab.ChoosedItem = activeTab.SelectedItem;
Refresh();
}
public Point GetLocation(AxSideTab whichTab)
{
int i = 0;
int lastUpperY = 0;
for (; i < sideTabs.Count; ++i) {
AxSideTab tab = sideTabs[i];
int yPos = i * (Font.Height + 4 + 1);
if (tab == whichTab) {
return new Point(0, yPos);
}
lastUpperY = yPos + Font.Height + 4;
if (tab == activeTab) {
break;
}
}
int bottom = Height;
for (int j = sideTabs.Count - 1; j > i; --j) {
AxSideTab tab = sideTabs[j];
int yPos = Height - (-j + sideTabs.Count ) * (Font.Height + 4 + 1);
if (yPos < lastUpperY + (Font.Height + 4 + 1))
break;
bottom = yPos;
if (tab == whichTab) {
return new Point(0, yPos);
}
}
return new Point(-1, -1);
}
public AxSideTab GetTabAt(int x, int y)
{
int lastUpperY = 0;
int i = 0;
for (; i < sideTabs.Count; ++i) {
AxSideTab tab = sideTabs[i];
int yPos = i * (Font.Height + 4 + 1);
lastUpperY = yPos + Font.Height + 4;
if (y >= yPos && y <= lastUpperY)
return tab;
if (tab == activeTab) {
break;
}
}
for (int j = sideTabs.Count - 1; j > i; --j) {
AxSideTab tab = sideTabs[j];
int yPos = Height - (-j + sideTabs.Count ) * (Font.Height + 4 + 1);
if (yPos < lastUpperY)
break;
if (y >= yPos && y <= yPos + Font.Height + 4)
return tab;
}
return null;
}
public int GetTabIndexAt(int x, int y)
{
int lastUpperY = 0;
int i = 0;
for (; i < sideTabs.Count; ++i) {
AxSideTab tab = sideTabs[i];
int yPos = i * (Font.Height + 4 + 1);
lastUpperY = yPos + Font.Height + 4;
if (y >= yPos && y <= lastUpperY)
return i;
if (tab == activeTab)
break;
}
for (int j = sideTabs.Count - 1; j > i; --j) {
AxSideTab tab = sideTabs[j];
int yPos = Height - (-j + sideTabs.Count ) * (Font.Height + 4 + 1);
if (yPos < lastUpperY + (Font.Height + 4 + 1))
break;
if (y >= yPos && y <= yPos + Font.Height + 4)
return j;
}
return -1;
}
static DragDropEffects GetDragDropEffect(DragEventArgs e)
{
if ((e.AllowedEffect & DragDropEffects.Move) > 0 &&
(e.AllowedEffect & DragDropEffects.Copy) > 0) {
return (e.KeyState & 8) > 0 ? DragDropEffects.Copy : DragDropEffects.Move;
} else if ((e.AllowedEffect & DragDropEffects.Move) > 0) {
return DragDropEffects.Move;
} else if ((e.AllowedEffect & DragDropEffects.Copy) > 0) {
return DragDropEffects.Copy;
}
return DragDropEffects.None;
}
protected override void OnDragEnter(DragEventArgs e)
{
ExitRenameMode();
base.OnDragEnter(e);
Point p = PointToClient(new Point(e.X, e.Y));
if (e.Data.GetDataPresent(typeof(AxSideTabItem))) {
e.Effect = (e.KeyState & 8) > 0 ? DragDropEffects.Copy : DragDropEffects.Move;
} else if (e.Data.GetDataPresent(typeof(AxSideTab))) {
AxSideTab tab = (AxSideTab)e.Data.GetData(typeof(AxSideTab));
if (Tabs.Contains(tab)) {
Tabs.DragOverTab = tab;
e.Effect = GetDragDropEffect(e);
} else {
e.Effect = DragDropEffects.None;
}
} else if (e.Data.GetDataPresent(typeof(string))) {
e.Effect = GetDragDropEffect(e);
} else {
e.Effect = DragDropEffects.None;
}
}
protected override void OnDragLeave(EventArgs e)
{
base.OnDragLeave(e);
Tabs.DragOverTab = null;
ClearDraggings(activeTab);
Refresh();
}
protected override void OnDragDrop(DragEventArgs e)
{
base.OnDragDrop(e);
Point p = PointToClient(new Point(e.X, e.Y));
if (e.Data.GetDataPresent(typeof(AxSideTabItem))) {
AxSideTabItem draggedItem = (AxSideTabItem)e.Data.GetData(typeof(AxSideTabItem));
// drag tabitem into other sideTab
AxSideTab tab = GetTabAt(p.X, p.Y);
if (tab != null) {
if (tab == Tabs.DragOverTab && tab.CanDragDrop) {
Tabs.DragOverTab.SideTabStatus = SideTabStatus.Normal;
draggedItem.SideTabItemStatus = SideTabItemStatus.Normal;
switch (e.Effect) {
case DragDropEffects.Move:
if (Tabs.DragOverTab != activeTab) {
activeTab.Items.Remove(draggedItem);
Tabs.DragOverTab.Items.Add(draggedItem);
}
break;
case DragDropEffects.Copy:
AxSideTabItem newItem = draggedItem.Clone();
Tabs.DragOverTab.Items.Add(newItem);
break;
}
Tabs.DragOverTab = null;
Refresh();
}
}
} else if (e.Data.GetDataPresent(typeof(string))) {
if (Tabs.DragOverTab != null) {
string str = (string)e.Data.GetData(typeof(string));
Tabs.DragOverTab.Items.Add("Text:" + str.Trim(), str);
}
Tabs.DragOverTab = null;
Refresh();
} else {
Tabs.DragOverTab = null;
Refresh();
}
}
void ClearDraggings(AxSideTab tab)
{
foreach (AxSideTabItem item in tab.Items) {
if (item.SideTabItemStatus == SideTabItemStatus.Drag) {
item.SideTabItemStatus = SideTabItemStatus.Normal;
}
}
}
protected override void OnDragOver(DragEventArgs e)
{
ExitRenameMode();
base.OnDragOver(e);
Point p = PointToClient(new Point(e.X, e.Y));
if (e.Data.GetDataPresent(typeof(AxSideTabItem))) {
ClearDraggings(activeTab);
AxSideTab tab = GetTabAt(p.X, p.Y);
if (tab != null && tab != Tabs.DragOverTab) {
if (tab.CanDragDrop) {
Tabs.DragOverTab = tab;
} else {
Tabs.DragOverTab = null;
}
Refresh();
}
if (Tabs.DragOverTab != null && Tabs.DragOverTab.CanDragDrop) {
e.Effect = GetDragDropEffect(e);
} else {
e.Effect = DragDropEffects.None;
}
} else if (e.Data.GetDataPresent(typeof(string))) {
AxSideTab oldTab = Tabs.DragOverTab;
if (activeTabMemberArea.Contains(p.X, p.Y)) {
Tabs.DragOverTab = activeTab;
} else {
Tabs.DragOverTab = GetTabAt(p.X, p.Y);
}
if (oldTab != Tabs.DragOverTab) {
Refresh();
}
} else if (e.Data.GetDataPresent(typeof(AxSideTab))) {
int tabIndex = GetTabIndexAt(p.X, p.Y);
if (tabIndex != -1) {
AxSideTab tab = Tabs.DragOverTab;
Tabs.Remove(tab);
Tabs.Insert(tabIndex, tab);
Refresh();
}
e.Effect = DragDropEffects.Move;
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -