mirror of
https://github.com/colhountech/DarkUI.Net5.git
synced 2024-10-17 07:16:49 +03:00
Added DarkScrollBase and DarkScrollView
Abstract classes that can be built on top of for scrollable controls. Use DarkScrollBase for non-GDI rendering and DarkScrollView for GDI rendering.
This commit is contained in:
parent
13c57d8162
commit
431cea92c8
294
DarkUI/Controls/DarkScrollBase.cs
Normal file
294
DarkUI/Controls/DarkScrollBase.cs
Normal file
@ -0,0 +1,294 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace DarkUI
|
||||
{
|
||||
public abstract class DarkScrollBase : Control
|
||||
{
|
||||
#region Event Region
|
||||
|
||||
public event EventHandler ViewportChanged;
|
||||
public event EventHandler ContentSizeChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Field Region
|
||||
|
||||
protected readonly DarkScrollBar _vScrollBar;
|
||||
protected readonly DarkScrollBar _hScrollBar;
|
||||
|
||||
private Size _visibleSize;
|
||||
private Size _contentSize;
|
||||
|
||||
private Rectangle _viewport;
|
||||
|
||||
private Point _offsetMousePosition;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Property Region
|
||||
|
||||
public Rectangle Viewport
|
||||
{
|
||||
get { return _viewport; }
|
||||
private set
|
||||
{
|
||||
_viewport = value;
|
||||
|
||||
if (ViewportChanged != null)
|
||||
ViewportChanged(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
public Size ContentSize
|
||||
{
|
||||
get { return _contentSize; }
|
||||
set
|
||||
{
|
||||
_contentSize = value;
|
||||
UpdateScrollBars();
|
||||
|
||||
if (ContentSizeChanged != null)
|
||||
ContentSizeChanged(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
public Point OffsetMousePosition
|
||||
{
|
||||
get { return _offsetMousePosition; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor Region
|
||||
|
||||
protected DarkScrollBase()
|
||||
{
|
||||
SetStyle(ControlStyles.Selectable |
|
||||
ControlStyles.UserMouse, true);
|
||||
|
||||
_vScrollBar = new DarkScrollBar { ScrollOrientation = DarkOrientation.Vertical };
|
||||
_hScrollBar = new DarkScrollBar { ScrollOrientation = DarkOrientation.Horizontal };
|
||||
|
||||
Controls.Add(_vScrollBar);
|
||||
Controls.Add(_hScrollBar);
|
||||
|
||||
_vScrollBar.ValueChanged += delegate { UpdateViewport(); };
|
||||
_hScrollBar.ValueChanged += delegate { UpdateViewport(); };
|
||||
|
||||
_vScrollBar.MouseDown += delegate { Select(); };
|
||||
_hScrollBar.MouseDown += delegate { Select(); };
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handler Region
|
||||
|
||||
protected override void OnCreateControl()
|
||||
{
|
||||
base.OnCreateControl();
|
||||
|
||||
UpdateScrollBars();
|
||||
}
|
||||
|
||||
protected override void OnGotFocus(EventArgs e)
|
||||
{
|
||||
base.OnGotFocus(e);
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override void OnLostFocus(EventArgs e)
|
||||
{
|
||||
base.OnLostFocus(e);
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override void OnResize(EventArgs e)
|
||||
{
|
||||
base.OnResize(e);
|
||||
|
||||
UpdateScrollBars();
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseMove(e);
|
||||
|
||||
_offsetMousePosition = new Point(e.X + Viewport.Left, e.Y + Viewport.Top);
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseDown(e);
|
||||
|
||||
if (e.Button == MouseButtons.Right)
|
||||
Select();
|
||||
}
|
||||
|
||||
protected override void OnMouseWheel(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseWheel(e);
|
||||
|
||||
var horizontal = false;
|
||||
|
||||
if (_hScrollBar.Visible && ModifierKeys == Keys.Control)
|
||||
horizontal = true;
|
||||
|
||||
if (_hScrollBar.Visible && !_vScrollBar.Visible)
|
||||
horizontal = true;
|
||||
|
||||
if (!horizontal)
|
||||
{
|
||||
if (e.Delta > 0)
|
||||
_vScrollBar.ScrollByPhysical(3);
|
||||
else if (e.Delta < 0)
|
||||
_vScrollBar.ScrollByPhysical(-3);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e.Delta > 0)
|
||||
_hScrollBar.ScrollByPhysical(3);
|
||||
else if (e.Delta < 0)
|
||||
_hScrollBar.ScrollByPhysical(-3);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e)
|
||||
{
|
||||
base.OnPreviewKeyDown(e);
|
||||
|
||||
// Allows arrow keys to trigger OnKeyPress
|
||||
switch (e.KeyCode)
|
||||
{
|
||||
case Keys.Up:
|
||||
case Keys.Down:
|
||||
case Keys.Left:
|
||||
case Keys.Right:
|
||||
e.IsInputKey = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Method Region
|
||||
|
||||
private void UpdateScrollBars()
|
||||
{
|
||||
if (_vScrollBar.Maximum != ContentSize.Height)
|
||||
_vScrollBar.Maximum = ContentSize.Height;
|
||||
|
||||
if (_hScrollBar.Maximum != ContentSize.Width)
|
||||
_hScrollBar.Maximum = ContentSize.Width;
|
||||
|
||||
var scrollSize = Consts.ScrollBarSize;
|
||||
|
||||
_vScrollBar.Location = new Point(ClientSize.Width - scrollSize, 0);
|
||||
_vScrollBar.Size = new Size(scrollSize, ClientSize.Height);
|
||||
|
||||
_hScrollBar.Location = new Point(0, ClientSize.Height - scrollSize);
|
||||
_hScrollBar.Size = new Size(ClientSize.Width, scrollSize);
|
||||
|
||||
if (DesignMode)
|
||||
return;
|
||||
|
||||
// Do this twice in case changing the visibility of the scrollbars
|
||||
// causes the VisibleSize to change in such a way as to require a second scrollbar.
|
||||
// Probably a better way to detect that scenario...
|
||||
SetVisibleSize();
|
||||
SetScrollBarVisibility();
|
||||
SetVisibleSize();
|
||||
SetScrollBarVisibility();
|
||||
|
||||
if (_vScrollBar.Visible)
|
||||
_hScrollBar.Width -= scrollSize;
|
||||
|
||||
if (_hScrollBar.Visible)
|
||||
_vScrollBar.Height -= scrollSize;
|
||||
|
||||
_vScrollBar.ViewSize = _visibleSize.Height;
|
||||
_hScrollBar.ViewSize = _visibleSize.Width;
|
||||
|
||||
UpdateViewport();
|
||||
}
|
||||
|
||||
private void SetScrollBarVisibility()
|
||||
{
|
||||
_vScrollBar.Visible = _visibleSize.Height < ContentSize.Height;
|
||||
_hScrollBar.Visible = _visibleSize.Width < ContentSize.Width;
|
||||
}
|
||||
|
||||
private void SetVisibleSize()
|
||||
{
|
||||
var scrollSize = Consts.ScrollBarSize;
|
||||
|
||||
_visibleSize = new Size(ClientSize.Width, ClientSize.Height);
|
||||
|
||||
if (_vScrollBar.Visible)
|
||||
_visibleSize.Width -= scrollSize;
|
||||
|
||||
if (_hScrollBar.Visible)
|
||||
_visibleSize.Height -= scrollSize;
|
||||
}
|
||||
|
||||
private void UpdateViewport()
|
||||
{
|
||||
var left = 0;
|
||||
var top = 0;
|
||||
var width = ClientSize.Width;
|
||||
var height = ClientSize.Height;
|
||||
|
||||
if (_hScrollBar.Visible)
|
||||
{
|
||||
left = _hScrollBar.Value;
|
||||
height -= _hScrollBar.Height;
|
||||
}
|
||||
|
||||
if (_vScrollBar.Visible)
|
||||
{
|
||||
top = _vScrollBar.Value;
|
||||
width -= _vScrollBar.Width;
|
||||
}
|
||||
|
||||
Viewport = new Rectangle(left, top, width, height);
|
||||
|
||||
var pos = PointToClient(MousePosition);
|
||||
_offsetMousePosition = new Point(pos.X + Viewport.Left, pos.Y + Viewport.Top);
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
public void ScrollTo(Point point)
|
||||
{
|
||||
HScrollTo(point.X);
|
||||
VScrollTo(point.Y);
|
||||
}
|
||||
|
||||
public void VScrollTo(int value)
|
||||
{
|
||||
if (_vScrollBar.Visible)
|
||||
_vScrollBar.Value = value;
|
||||
}
|
||||
|
||||
public void HScrollTo(int value)
|
||||
{
|
||||
if (_hScrollBar.Visible)
|
||||
_hScrollBar.Value = value;
|
||||
}
|
||||
|
||||
public Point PointToView(Point point)
|
||||
{
|
||||
return new Point(point.X - Viewport.Left, point.Y - Viewport.Top);
|
||||
}
|
||||
|
||||
public Rectangle RectangleToView(Rectangle rect)
|
||||
{
|
||||
return new Rectangle(new Point(rect.Left - Viewport.Left, rect.Top - Viewport.Top), rect.Size);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
60
DarkUI/Controls/DarkScrollView.cs
Normal file
60
DarkUI/Controls/DarkScrollView.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace DarkUI
|
||||
{
|
||||
public abstract class DarkScrollView : DarkScrollBase
|
||||
{
|
||||
#region Constructor Region
|
||||
|
||||
protected DarkScrollView()
|
||||
{
|
||||
SetStyle(ControlStyles.OptimizedDoubleBuffer |
|
||||
ControlStyles.ResizeRedraw |
|
||||
ControlStyles.UserPaint, true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Paint Region
|
||||
|
||||
protected abstract void PaintContent(Graphics g);
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
var g = e.Graphics;
|
||||
|
||||
// Draw background
|
||||
using (var b = new SolidBrush(BackColor))
|
||||
{
|
||||
g.FillRectangle(b, ClientRectangle);
|
||||
}
|
||||
|
||||
// Offset the graphics based on the viewport, render the control contents, then reset it.
|
||||
g.TranslateTransform(Viewport.Left * -1, Viewport.Top * -1);
|
||||
|
||||
PaintContent(g);
|
||||
|
||||
g.TranslateTransform(Viewport.Left, Viewport.Top);
|
||||
|
||||
// Draw the bit where the scrollbars meet
|
||||
if (_vScrollBar.Visible && _hScrollBar.Visible)
|
||||
{
|
||||
using (var b = new SolidBrush(BackColor))
|
||||
{
|
||||
var rect = new Rectangle(_hScrollBar.Right, _vScrollBar.Bottom, _vScrollBar.Width,
|
||||
_hScrollBar.Height);
|
||||
|
||||
g.FillRectangle(b, rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPaintBackground(PaintEventArgs e)
|
||||
{
|
||||
// Absorb event
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -41,6 +41,9 @@
|
||||
<Compile Include="Config\Colors.cs" />
|
||||
<Compile Include="Config\Consts.cs" />
|
||||
<Compile Include="Config\Enums.cs" />
|
||||
<Compile Include="Controls\DarkScrollBase.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Controls\DarkButton.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
|
Loading…
Reference in New Issue
Block a user