📄 tabcontrol.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.Text;
using System.Drawing;
using System.Resources;
using System.Reflection;
using System.Collections;
using System.Drawing.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing.Imaging;
using Microsoft.Win32;
using Crownwood.Magic.Win32;
using Crownwood.Magic.Menus;
using Crownwood.Magic.Common;
using Crownwood.Magic.Collections;
namespace Crownwood.Magic.Controls
{
[ToolboxBitmap(typeof(TabControl))]
[DefaultProperty("Appearance")]
[DefaultEvent("SelectionChanged")]
[Designer(typeof(Crownwood.Magic.Controls.TabControlDesigner))]
public class TabControl : UserControl
{
// Enumeration of appearance styles
public enum VisualAppearance
{
MultiDocument = 0,
MultiForm = 1,
MultiBox = 2
}
// Enumeration of modes that control display of the tabs area
public enum HideTabsModes
{
ShowAlways,
HideAlways,
HideUsingLogic,
HideWithoutMouse
}
// Indexes into the menu images strip
protected enum ImageStrip
{
LeftEnabled = 0,
LeftDisabled = 1,
RightEnabled = 2,
RightDisabled = 3,
Close = 4,
Error = 5
}
// Enumeration of Indexes into positioning constants array
protected enum PositionIndex
{
BorderTop = 0,
BorderLeft = 1,
BorderBottom = 2,
BorderRight = 3,
ImageGapTop = 4,
ImageGapLeft = 5,
ImageGapBottom = 6,
ImageGapRight = 7,
TextOffset = 8,
TextGapLeft = 9,
TabsBottomGap = 10,
ButtonOffset = 11,
}
// Helper class for handling multiline calculations
protected class MultiRect
{
protected Rectangle _rect;
protected int _index;
public MultiRect(Rectangle rect, int index)
{
_rect = rect;
_index = index;
}
public int Index
{
get { return _index; }
}
public Rectangle Rect
{
get { return _rect; }
set { _rect = value; }
}
public int X
{
get { return _rect.X; }
set { _rect.X = value; }
}
public int Y
{
get { return _rect.Y; }
set { _rect.Y = value; }
}
public int Width
{
get { return _rect.Width; }
set { _rect.Width = value; }
}
public int Height
{
get { return _rect.Height; }
set { _rect.Height = value; }
}
}
protected class HostPanel : Panel
{
public HostPanel()
{
// Prevent flicker with double buffering and all painting inside WM_PAINT
SetStyle(ControlStyles.DoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnResize(EventArgs e)
{
// Update size of each child to match ourself
foreach(Control c in this.Controls)
c.Size = this.Size;
base.OnResize(e);
}
}
// Class constants for sizing/positioning each style
protected static int[,] _position = {
{3, 1, 1, 1, 1, 2, 1, 1, 2, 1, 3, 2}, // IDE
{6, 2, 2, 3, 3, 1, 1, 0, 1, 1, 2, 0} // Plain
};
// Class constants
protected static int _plainBorder = 3;
protected static int _plainBorderDouble = 6;
protected static int _tabsAreaStartInset = 5;
protected static int _tabsAreaEndInset = 5;
protected static float _alphaIDE = 1.5F;
protected static int _buttonGap = 3;
protected static int _buttonWidth = 14;
protected static int _buttonHeight = 14;
protected static int _imageButtonWidth = 12;
protected static int _imageButtonHeight = 12;
protected static int _multiBoxAdjust = 2;
protected readonly Rectangle _nullPosition = new Rectangle(-999, -999, 0, 0);
// Class state
protected static ImageList _internalImages;
// Instance fields - size/positioning
protected int _textHeight;
protected int _imageWidth;
protected int _imageHeight;
protected int _imageGapTopExtra;
protected int _imageGapBottomExtra;
protected Rectangle _pageRect;
protected Rectangle _pageAreaRect;
protected Rectangle _tabsAreaRect;
// Instance fields - state
protected int _ctrlTopOffset; // How far from top edge embedded controls should offset
protected int _ctrlLeftOffset; // How far from left edge embedded controls should offset
protected int _ctrlRightOffset; // How far from right edgeembedded controls should offset
protected int _ctrlBottomOffset; // How far from bottom edge embedded controls should offset
protected int _styleIndex; // Index into position array
protected int _pageSelected; // index of currently selected page (-1 is none)
protected int _startPage; // index of first page to draw, used when scrolling pages
protected int _hotTrackPage; // which page is currently displayed as being tracked
protected int _topYPos; // Y position of first line in multiline mode
protected int _bottomYPos; // Y position of last line in multiline mode
protected int _leaveTimeout; // How long from leaving to timeout occuring
protected bool _dragFromControl; // Must drag away from whole control before drag events generated
protected bool _mouseOver; // Mouse currently over the control (or child pages)
protected bool _multiline; // should tabs that cannot fit on a line create new lines
protected bool _multilineFullWidth; // when in multiline mode, all lines are extended to end
protected bool _shrinkPagesToFit; // pages are shrunk so they all fit in control width
protected bool _changed; // Flag for use when updating contents of collection
protected bool _positionAtTop; // display tabs at top or bottom of the control
protected bool _showClose; // should the close button be displayed
protected bool _showArrows; // should then scroll arrow be displayed
protected bool _insetPlain; // Show the inset border for controls
protected bool _insetBorderPagesOnly; // Remove the border entirely for Plain mode
protected bool _selectedTextOnly; // Only draw text for selected tab
protected bool _rightScroll; // Should the right scroll button be enabled
protected bool _leftScroll; // Should the left scroll button be enabled
protected bool _dimUnselected; // should unselected pages be drawn slightly dimmed
protected bool _boldSelected; // should selected page use a bold font
protected bool _hotTrack; // should mouve moving over text hot track it
protected bool _hoverSelect; // select a page when he mouse hovers over it
protected bool _recalculate; // flag to indicate recalculation is needed before painting
protected bool _leftMouseDown; // Is the left mouse button down
protected bool _leftMouseDownDrag; // Has a drag operation begun
protected bool _ignoreDownDrag; // When pressed the left button cannot generate two drags
protected bool _defaultColor; // Is the background color the default one?
protected bool _defaultFont; // Is the Font the default one?
protected bool _recordFocus; // Record the control with focus when leaving a page
protected bool _idePixelArea; // Place a one pixel border at top/bottom of tabs area
protected bool _idePixelBorder; // Place a one pixel border around control
protected PopupMenu _contextMenu; // Context menu to show on right mouse up
protected Point _leftMouseDownPos; // Initial mouse down position for left mouse button
protected Color _hotTextColor; // color for use when drawing text as hot
protected Color _textColor; // color for use when text not hot
protected Color _textInactiveColor; // color for use when text not hot and not the active tab
protected Color _backIDE; // background drawing color when in IDE appearance
protected Color _buttonActiveColor; // color for drawing buttons images when active
protected Color _buttonInactiveColor; // color for drawing buttons images when inactive
protected Color _backLight; // light variation of the back color
protected Color _backLightLight; // lightlight variation of the back color
protected Color _backDark; // dark variation of the back color
protected Color _backDarkDark; // darkdark variation of the back color
protected VisualStyle _style; // which style of use
protected HideTabsModes _hideTabsMode; // Decide when to hide/show tabs area
protected Timer _overTimer; // Time when mouse has left control
protected HostPanel _hostPanel; // Hosts the page instance control/form
protected VisualAppearance _appearance; // which appearance style
protected ImageList _imageList; // collection of images for use is tabs
protected ArrayList _tabRects; // display rectangles for associated page
protected TabPageCollection _tabPages; // collection of pages
// Instance fields - buttons
protected InertButton _closeButton;
protected InertButton _leftArrow;
protected InertButton _rightArrow;
public delegate void DoubleClickTabHandler(TabControl sender, TabPage page);
// Exposed events
public event EventHandler ClosePressed;
public event EventHandler SelectionChanging;
public event EventHandler SelectionChanged;
public event EventHandler PageGotFocus;
public event EventHandler PageLostFocus;
public event CancelEventHandler PopupMenuDisplay;
public event MouseEventHandler PageDragStart;
public event MouseEventHandler PageDragMove;
public event MouseEventHandler PageDragEnd;
public event MouseEventHandler PageDragQuit;
public event DoubleClickTabHandler DoubleClickTab;
static TabControl()
{
// Create a strip of images by loading an embedded bitmap resource
_internalImages = ResourceHelper.LoadBitmapStrip(Type.GetType("Crownwood.Magic.Controls.TabControl"),
"Crownwood.Magic.Resources.ImagesTabControl.bmp",
new Size(_imageButtonWidth, _imageButtonHeight),
new Point(0,0));
}
public TabControl()
{
// Prevent flicker with double buffering and all painting inside WM_PAINT
SetStyle(ControlStyles.DoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.UserPaint, true);
// Create collections
_tabRects = new ArrayList();
_tabPages = new TabPageCollection();
// Hookup to collection events
_tabPages.Clearing += new CollectionClear(OnClearingPages);
_tabPages.Cleared += new CollectionClear(OnClearedPages);
_tabPages.Inserting += new CollectionChange(OnInsertingPage);
_tabPages.Inserted += new CollectionChange(OnInsertedPage);
_tabPages.Removing += new CollectionChange(OnRemovingPage);
_tabPages.Removed += new CollectionChange(OnRemovedPage);
// Define the default state of the control
_startPage = -1;
_pageSelected = -1;
_hotTrackPage = -1;
_imageList = null;
_insetPlain = true;
_multiline = false;
_multilineFullWidth = false;
_dragFromControl = true;
_mouseOver = false;
_leftScroll = false;
_defaultFont = true;
_defaultColor = true;
_rightScroll = false;
_hoverSelect = false;
_leftMouseDown = false;
_ignoreDownDrag = true;
_selectedTextOnly = false;
_leftMouseDownDrag = false;
_insetBorderPagesOnly = false;
_hideTabsMode = HideTabsModes.ShowAlways;
_recordFocus = true;
_styleIndex = 1;
_leaveTimeout = 200;
_ctrlTopOffset = 0;
_ctrlLeftOffset = 0;
_ctrlRightOffset = 0;
_ctrlBottomOffset = 0;
_style = VisualStyle.IDE;
_buttonActiveColor = Color.FromArgb(128, this.ForeColor);
_buttonInactiveColor = _buttonActiveColor;
_textColor = TabControl.DefaultForeColor;
_textInactiveColor = Color.FromArgb(128, _textColor);
_hotTextColor = SystemColors.ActiveCaption;
// Create the panel that hosts each page control. This is done to prevent the problem where a
// hosted Control/Form has 'AutoScaleBaseSize' defined. In which case our attempt to size it the
// first time is ignored and the control sizes itself to big and would overlap the tabs area.
_hostPanel = new HostPanel();
_hostPanel.Location = new Point(-1,-1);
_hostPanel.Size = new Size(0,0);
_hostPanel.MouseEnter += new EventHandler(OnPageMouseEnter);
_hostPanel.MouseLeave += new EventHandler(OnPageMouseLeave);
// Create hover buttons
_closeButton = new InertButton(_internalImages, (int)ImageStrip.Close);
_leftArrow = new InertButton(_internalImages, (int)ImageStrip.LeftEnabled, (int)ImageStrip.LeftDisabled);
_rightArrow = new InertButton(_internalImages, (int)ImageStrip.RightEnabled, (int)ImageStrip.RightDisabled);
// We want our buttons to have very thin borders
_closeButton.BorderWidth = _leftArrow.BorderWidth = _rightArrow.BorderWidth = 1;
// Hookup to the button events
_closeButton.Click += new EventHandler(OnCloseButton);
_leftArrow.Click += new EventHandler(OnLeftArrow);
_rightArrow.Click += new EventHandler(OnRightArrow);
// Set their fixed sizes
_leftArrow.Size = _rightArrow.Size = _closeButton.Size = new Size(_buttonWidth, _buttonHeight);
// Add child controls
Controls.AddRange(new Control[]{_closeButton, _leftArrow, _rightArrow, _hostPanel});
// Grab some contant values
_imageWidth = 16;
_imageHeight = 16;
// Default to having a MultiForm usage
SetAppearance(VisualAppearance.MultiForm);
// Need a timer so that when the mouse leaves, a fractionaly delay occurs before
// noticing and hiding the tabs area when the appropriate style is set
_overTimer = new Timer();
_overTimer.Interval = _leaveTimeout;
_overTimer.Tick += new EventHandler(OnMouseTick);
// Need notification when the MenuFont is changed
Microsoft.Win32.SystemEvents.UserPreferenceChanged +=
new UserPreferenceChangedEventHandler(OnPreferenceChanged);
// Define the default Font, BackColor and Button images
DefineFont(SystemInformation.MenuFont);
DefineBackColor(SystemColors.Control);
DefineButtonImages();
Recalculate();
}
protected override void Dispose( bool disposing )
{
if(disposing)
{
// Remove notifications
Microsoft.Win32.SystemEvents.UserPreferenceChanged -=
new UserPreferenceChangedEventHandler(OnPreferenceChanged);
}
base.Dispose(disposing);
}
[Category("Appearance")]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -